Using Ajax with a Class file

The question:

At the moment I have an ajax that works (I get a success [200] response), but having an issue with the action hooks on the response. The JSON object is not coming back, instead I’m getting a 0.

I have the die(); after my return so I’m thinking the issue is the hook not working.

I’ve tried multiple methods within the Class constructor but I’m not sure if this approach is right, I’ve done it before with a plugin I made, but this is within the theme.

Form.php

(included in functions.php with add_action('after_setup_theme')

public function __construct(){
 // Test #1
 add_action( 'wp_ajax_nopriv_process_reservation', array( &$this, 'process_reservation' ) );

 // Test #2 
 add_action( 'wp_ajax_process_reservation', &$this->process_reservation ); //with and without '&' before $this

 // Test #3 (this is incorrect)
 add_action( 'wp_ajax_nopriv_process_reservation', $this->process_reservation );


//If I wrap this with **add_action('init',function(){... *** then it does not load
 wp_enqueue_script('ajax_script',THEME_MODULES_URL.'/Reservations/form.js',array('jquery'),TRUE);
 wp_localize_script( 'ajax_script', 'myAjax', array(
      'ajaxurl'               => admin_url( 'admin-ajax.php' ), //don't change this
      'itemNonce'             => wp_create_nonce("ajax_nonce"), //don't change this
  ));
}

Just in case it is needed here is the test of my callback function at the moment as well

private function process_reservation(){
    check_ajax_referer( 'process_reservation_nonce', 'nonce' );

    if( true )
        wp_send_json_success( 'ok' );
    else
        wp_send_json_error( array( 'error' => $custom_error ) );

}

Form data in the XHR console shows both the action and nounce passed

action:process_reservation
ajax_nonce:6f155a1e17

I’ve done enough Ajax to know what to expect so I’m pretty sure its a hooking issue here, perhaps something with the theme scope that I don’t understand, either way any suggestions or help from the community would be great! Thanks in advance

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

The errors I’ve spotted in your code:

One was pointed by @helgatheviking in a comment: the Ajax callback has to be a public method, not private.

Not sure how are you initializing this class, but wp_enqueue_script&_style (in singular) has to be encapsulated inside a wp_enqueue_scripts hook (WP_DEBUG dumps a notice).

You can drop the & from $this, that’s PHP 4. Follows a working example:

class MyTheme
{
    public function __construct()
    {
        add_action( 'wp_footer', array( $this, 'aux_function' ) );
        add_action( 'wp_enqueue_scripts', array( $this, 'init_plugin' ) );
        add_action( 'wp_ajax_process_reservation', array( $this, 'process_reservation' ) ); 
        add_action( 'wp_ajax_nopriv_process_reservation', array( $this, 'process_reservation' ) );
    }

    public function aux_function()
    {
        echo '<h4><a href="#" rel="nofollow noreferrer noopener" id="wpse">TEST AJAX</a></h4>';
    }

    public function init_plugin()
    {
        wp_enqueue_script( 
            'ajax_script', 
            plugins_url( '/test.js',__FILE__ ), 
            array('jquery'), 
            TRUE 
        );
        wp_localize_script( 
            'ajax_script', 
            'myAjax', 
            array(
                'url'   => admin_url( 'admin-ajax.php' ),
                'nonce' => wp_create_nonce( "process_reservation_nonce" ),
            )
        );
    }

    public function process_reservation()
    {
        check_ajax_referer( 'process_reservation_nonce', 'nonce' );

        if( true )
            wp_send_json_success( 'Ajax here!' );
        else
            wp_send_json_error( array( 'error' => $custom_error ) );
    }
}
new MyTheme();

test.js

jQuery(document).ready(function($) 
{
    $('#wpse').click(function(e) 
    {
        e.preventDefault();
        var data = {
            action: 'process_reservation',
            nonce: myAjax.nonce
        };

        $.post( myAjax.url, data, function( response ) 
        {
            $('#wpse').html( response.data );
        });
    });
});

Method 2

The issue was that in my functions.php I was loading a file (reservations.php) using the after_setup_theme hook

add_action('after_setup_theme', 'init_cpts');

And then from within the file that was loaded I was requiring my class files with the init hook. I thought this would be ok since init loads after after_setup_theme, it looked like this”

function load_classes(){
    require_once( PATH_TO_FILE .'/Class.php');
}
add_action('init','load_classes');

The problem as mentioned in @brasofilo thread was that any action hook I attempted once in the class file would no longer work, because at this point the init had already been triggered.

To fix this I simple removed the loaded_classes() as shown above, and instead just required_once within the file itself (which is loaded after_setup_theme). Then @brasofilo answer worked like a charm so make sure to +1 his response.

Method 3

Please check your ajax call

if you use make sure you put dataType : “json”


$.ajax({
  dataType: "json",
  url: url,
  data: data,
  success: success
});

or use $.getJSON() function …

Hope this fix the issue.


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

Leave a Comment