Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

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

share|improve this question
1  
See debugging AJAX. Tried that? –  toscho Jul 13 '13 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. –  Xtremefaith Jul 13 '13 at 21:01
1  
Maybe because the callback method is set to private? Any difference if process_reservation() is public? Just guessing here. –  helgatheviking Jul 13 '13 at 21:52
add comment

3 Answers

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 );
        });
    });
});
share|improve this answer
    
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 –  Xtremefaith Jul 16 '13 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 –  Xtremefaith Jul 16 '13 at 2:01
    
@Xtremefaith, I've re-written the code to be PHP 5.2 compatible. –  brasofilo Jul 16 '13 at 2:31
add comment
up vote 1 down vote accepted

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.

share|improve this answer
    
How about upvoting his response yourself? ;) –  Johannes Pille Jul 16 '13 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 –  Xtremefaith Jul 16 '13 at 17:17
    
Makes sense. :) –  Johannes Pille Jul 17 '13 at 1:56
add comment

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.

share|improve this answer
    
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 –  Xtremefaith Jul 16 '13 at 1:36
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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