7

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

3
  • 1
    See debugging AJAX. Tried that?
    – fuxia
    Jul 13, 2013 at 20:46
  • I just did thank you. I got a response as expected: X-Debug-Ajax-1:File "C:\...\wp-content\themes\bp\functions.php" was called on an AJAX request. X-Debug-Ajax-2:Function "t5_debug_test" was called and the user is not logged in. X-Frame-Options:SAMEORIGIN X-Powered-By:PHP/5.4.7 X-Robots-Tag:noindex I don't think its an ajax issue, thinking just the action hook not firing. Jul 13, 2013 at 21:01
  • 2
    Maybe because the callback method is set to private? Any difference if process_reservation() is public? Just guessing here. Jul 13, 2013 at 21:52

3 Answers 3

24

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="#" 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 );
        });
    });
});
3
  • So using your example here I got this to work, but then when I started converting it 1 piece at a time I run into issues, again with the hooks. For example, the add_action( 'init', function() { wrapper around the wp_enqueue() breaks; only when I remove that does the script get enqueued. The only difference I see in your example is yours is inside functions.php file, but my example is in a separate file included in a add_action('after_setup_theme', 'load_class_file'); inside functions.php Jul 16, 2013 at 1:33
  • For example, at the moment in my __contructor() even something simple like your add_action( 'wp_head', function() { echo '<h4><a href="#" id="wpse">TEST AJAX</a></h4>'; }); doesn't work unless I remove the add_action wrap Jul 16, 2013 at 2:01
  • @Xtremefaith, I've re-written the code to be PHP 5.2 compatible.
    – brasofilo
    Jul 16, 2013 at 2:31
4

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.

3
  • How about upvoting his response yourself? ;) Jul 16, 2013 at 8:28
  • 1
    I tried, my reputation is too low (11) needs to be at 15. So once I get a few more rep points I will. Thanks @JohannesPille Jul 16, 2013 at 17:17
  • Makes sense. :) Jul 17, 2013 at 1:56
0

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.

1
  • This is not the issue, ajax is being called and getting a response of 200 as expected. But no action is being called, hence returning 0 from the die(0) in the admin-ajax.php Jul 16, 2013 at 1:36

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.