I've checked any threads here regarding this and did a debug test which worked, I'd like to understand why my own code doesn't work as it presents the same functionality explained in every possible thread created about this issue.

I'm trying to send AJAX request when clicking on a checkbox and do some work with MySQL.

Here are some details to understand the scope and what was done:

var $ = jQuery;
$(function() {
    $('table.table').on('click', '[name="term-id"]', function() {
        var t = $(this),
            id = t.val(),
            checked = t.is(':checked');

        checkCategory(id, checked);

function checkCategory(id, checked) {
        url: ajaxurl,
        type: 'POST',
        dataType: 'json',
        data: {action: 'setAsyncCheckProduct', id: id, checked: checked},
        success: function(response) {
        error: function(errorThrown) {

This script is included in my plugin via:

wp_enqueue_script('settings-manager', $this->pluginUrl . '/assets/js/SettingsManager.js');

In my main (abstract) plugin class (It is instantiated and is getting called, so I omit this code sample), but I add my async events assigned to admin_init:

add_action('admin_init', [$this, 'assignAsyncEvents']);

In my concrete classes, I implement this method like:

public function setAsyncCheckProduct()
    echo 123123123;

public function assignAsyncEvents()
    add_action('wp_ajax_setAsyncCheckProduct', [$this, 'setAsyncCheckProduct']);

Which basically means:

Send AJAX request to whatever is "ajaxurl" (which returns correct: /wp-admin/admin-ajax.php), action: setAsyncCheckProduct is sent along to the server, on the server, the assignAsyncEvents should be already done and a wp_ajax_MY_ACTION_NAME assigned.

Why do I still get a 0 in response?


UPDATE I've been manually putting debug output in admin-ajax.php just for the sake of curiosity.

if ( is_user_logged_in() ) {
     * Fires authenticated AJAX actions for logged-in users.
     * The dynamic portion of the hook name, `$_REQUEST['action']`,
     * refers to the name of the AJAX action callback being fired.
     * @since 2.1.0
    do_action( 'wp_ajax_' . $_REQUEST['action'] );
    var_dump('wp_ajax_' . $_REQUEST['action']);
} else {
     * Fires non-authenticated AJAX actions for logged-out users.
     * The dynamic portion of the hook name, `$_REQUEST['action']`,
     * refers to the name of the AJAX action callback being fired.
     * @since 2.8.0
    do_action( 'wp_ajax_nopriv_' . $_REQUEST['action'] );
// Default status
die( '0' );

This is the core functionality with my var_dump added. My AJAX call GETS THERE and the output is CORRECT ACTION NAME defined in add_action in my plugin files, thought nothing is returned from my action/it's not being called and I get to the default die( '0' );

Bummer. Don't know what to do further.

  • 1
    Try this: add_action( 'wp_ajax_setAsyncCheckProduct', array( $this, 'setAsyncCheckProduct' ) ); Jun 14, 2015 at 11:18
  • Add add_action('wp_ajax_nopriv_setAsyncCheckProduct', [$this, 'setAsyncCheckProduct']); too inside assignAsyncEvents()
    – passatgt
    Jun 14, 2015 at 11:21
  • @Nilambar your suggestion is just to remove shorthand array declaration. Jun 14, 2015 at 12:11
  • @passatgt this is not working, nor it should, as I'm working in admin panel, the user is always logged in and privileged. Jun 14, 2015 at 12:12
  • Just to experiment remove the var_dump() from the setAsyncCheckProduct() function. I want to say I ran into this issue a few months ago and want to say dumping inside that function caused me issues for some reason. Jun 14, 2015 at 13:09

2 Answers 2


The problem is where you place the add_action of your wp_ajax_*

Try to put it at the start of everything, and ensuring that it is being loaded in a /wp-admin/ route.

Try your url: http://xxx/wp-admin/admin-ajax.php?action=your_action until it gives you something different than zero.


Placing this answer for those people who're trying to fix the same issue.

It's important where

add_action('wp_ajax_setAsyncCheckProduct', [$this, 'setAsyncCheckProduct']);


In my case the issue was finally fixed moving a similar line to the main plugin file, where all concrete classes are included and initialised. Of course the line had to be changed to this form:

add_action('wp_ajax_setAsyncCheckProduct', ['ClassName', 'setAsyncCheckProduct']);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.