How can I send data to admin-ajax via JS Fetch?

I’m trying to implement filter system in my website. I decided to make it via js. I created fetch function

let filters = document.querySelectorAll('.filters-item');
let pageUrl = wp.page_url;
const postsContainer = document.querySelectorAll('.column.is-half.is-offset-1');
filters.forEach( (item) => {
        item.addEventListener('change', (e) =>{
            let url = pageUrl + '/wp-admin/admin-ajax.php';

            fetch(url, {
                method: 'POST',
                headers: {
                    'Content-Type': 'text/html; charset=UTF-8',
                },
                body: JSON.stringify({
                    'test': "sampledatatest",
                })
            }).then( function (response) {
                if(response.ok) {
                    return response.json();
                }
                return Promise.reject(response);
            }).then(function (data) {
                console.log(data);
            }).catch(function (error) {
                console.warn('Error', error);
            });
        });
    });

In my functions.php file I have simple function

add_action('wp_ajax_myfilter', 'misha_filter_function'); // wp_ajax_{ACTION HERE}
add_action('wp_ajax_nopriv_myfilter', 'misha_filter_function');

function misha_filter_function(){
    $t = $_POST['test'];
    echo $t;

    die();
}

When I click on filter item I’m getting error 400 in my dev console. What am I missing? Is it proper way to pass the data in the form like I did? I don’t want to use jQuery.

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

Is it proper way to pass the data in the form like I did?

If you mean the body part (of your fetch() call), then yes, it is okay.

However,

  1. You must send a query named action as part of the request (e.g. via the URL like example.com/wp-admin/admin-ajax.php?action=test), so that WordPress knows what AJAX action is it and then execute the callback(s) for that specific action.

    See here for further information, but in your case, the AJAX action is myfilter as in wp_ajax_myfilter and the callback is misha_filter_function().

  2. The Content-Type header doesn’t match the request body and you should’ve used application/json instead of text/html.

But then, even with the correct request body and headers, the admin-ajax.php doesn’t actually support JSON request, so if you want to send JSON request, then you should use the WordPress REST API and you’d probably want to add a custom endpoint like my-plugin/v1/myfilter.

Otherwise, and if you prefer using the admin-ajax.php, then for example, you can use the FormData() API in JavaScript to properly build the form data to be sent to admin-ajax.php:

var formData = new FormData();

formData.append( 'action', 'myfilter' );
formData.append( 'test', 'foo bar baz' );

fetch( url, {
    method: 'POST',
    body: formData,
} ) // wrapped
    .then( res => res.text() )
    .then( data => console.log( data ) )
    .catch( err => console.log( err ) );


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x