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.

One JS file is making an ajax call. Within the success of this ajax call another AJAX call is made. The second call checks whether the email has already been registered. If it has been then the second AJAX call recieves no returned data as shown in firebug and Chrome console in the case. But the same code works just fine in localhost while the mentioned problem takes place ONLY in online server.

The hosted page is at http://twmobilefitness.com/signup/. The problem takes place when you click on the 'Register Now' link at the end. You have to register twice with the same email address if you want to get the problem happen.

JS:

$.ajax( {
    url : base_url+"/wp-admin/admin-ajax.php",
    type : 'GET',
    cache : false,
    data : 'action=check_user_name&'
           + Math.floor( ( Math.random() * 100 ) +1 )
           + '&user_name='+user_name,
    success : function( result ) {
        if ( parseInt( result ) == 0 ) {
            $( ".result" ).html( '<span class="error">User name not available </span>' );
        } else if ( parseInt( result ) == 1 ) {
            $.ajax( {
                url : base_url 
                    + "/wp-admin/admin-ajax.php",
                type : 'GET',
                cache : false,
                data : 'action=check_email_used&'
                    + Math.floor( ( Math.random() *100 ) +1 )
                    + '&email=' + email,
                success : function( result_email ) {
                    if ( parseInt( result_email ) == 0 ) {
                        $( ".result" ).html( '<span class="error">Email already used </span>' );
                    } else if ( parseInt( result_email ) == 1 ) {
                        $( ".result" ).html( '' );      
                        $( ".signup_div" ).hide();
                        $( ".signup_emergency_contact" ).show();
                    }
                }
            } );
        }
    }   
} );    

functions.php has

add_action('wp_ajax_check_user_name','check_user_name');
add_action('wp_ajax_nopriv_check_user_name','check_user_name');

add_action( 'wp_ajax_check_email_used','check_email_used' );
add_action( 'wp_ajax_nopriv_check_email_used','check_email_used' );
function check_user_name() {
    global $wpdb;

    $user_name = trim( $_GET['user_name'] );
    $MobTraining = new MobTraining();
    $table =trim( "{$wpdb->prefix}users" );
    $array_where['user_login'] = $user_name;
    $sql_fetch = $MobTraining->fetch( $table, $array_where );
    $row = $wpdb->get_results( $sql_fetch, ARRAY_A );
    if ( sizeof( $row ) != 0 ) {
        echo '0';
    } else {
        echo '1';
    }
    die();
}

function check_email_used() {
    global $wpdb;

    $email = trim( $_GET['email'] );
    $MobTraining = new MobTraining();
    $table = trim( "{$wpdb->prefix}users" );
    $array_where['user_email'] = $email;
    $sql_fetch = "SELECT * FROM $table WHERE `user_email`='$email'";
    $row = $wpdb->get_results( $sql_fetch, ARRAY_A );
    if ( sizeof( $row ) != 0 ) {
        echo '0';
    } else {
        echo '1';
    }
    die();
}

How to make the code work in online server ?

share|improve this question
    
Before we take look at this: Please fix your code formatting. This is not readable. –  kaiser Oct 14 '13 at 11:17
1  
I know fixed your code. For the future: Make code as easy to read as possible for other readers and people who want to help you. –  kaiser Oct 14 '13 at 12:02
    
Btw, You still have to fix the PHP part. –  kaiser Oct 14 '13 at 12:11
1  
@kaiser. Really I understand. formatted php code again –  Istiaque Ahmed Oct 14 '13 at 12:18
add comment

1 Answer

What you're experiencing (AJAX works locally, but not on the server) is a delay problem. Locally everything works that fast, that you can't see your problem. In short your problem is the following:

AJAX callback (A) executes > AJAX Callback (B) doesn't know that it has to wait for (A) > You can't see the problem in your local install as (A) is finished too fast.

So you need to find a way how to tell your Callback (B) that it has to wait for (A). Here's how:

Register Scripts and move data from PHP to JS

Register and enqueue and localize your data the right way: Wrap it in a function or method and hook it to wp_enqueue_scripts (public/themes), login_enqueue_scripts (password/login/register) or admin_enqueue_scripts. The use wp_localize_script() to move data from PHP to JS and make it accessible there.

add_action( 'admin_enqueue_scripts', 'wpse118772jsObject' );
function wpse118772jsObject()
{
    $scriptHandle = 'custom-script-name';
    // Should be divided into separate functions or methods
    wp_register_script(
        $scriptHandle,
        plugins_url( __FILE__, 'your/path' ),
        array( 'jquery' ),
        plugin_dir_path( __FILE__ ).'your/path' ),
        true
    );

    wp_enqueue_script( $scriptHandle );

    wp_localize_script(
        $scriptHandle,
        'pluginObject',
        array(
                'ajaxURl' => admin_url( 'admin_ajax.php' ),
                'custom'  => array(
                        // custom data in here
                ),
        ),
    );
}

How to use jQuery AJAX the proper way.

There're several functions you can use: The default $.ajax({}); function or their shortcuts $.post();, $.getJSON();, etc.

So you can simply use something like the following - using the success/fail object methods.

( function( $, plugin ) {
    "use strict";

    $.ajax( {
        url : plugin.ajaxURl,
        data : {
            // other data
        },
        // We assume you're responding with a proper wp_send_json_success/error() in the PHP Cb.
        dataType : "json",

        // Request transformation possible in here.
        beforeSend : function( xhr ) {
            // Example:
            // xhr.overrideMimeType( 'application/json' );
        },

        // The actual handlers
        success : function( data, textStatus, jqXHR ) {
            // Handle data transformation or DOM manipulation in here.
        },
        error : function( jqXHR, textStatus, errorThrown ) {
            // silent: Log the error
            console.info( errorThrown );
            // loud: Throw Exception
            throw errorThrown;
        }
    } );
} )( jQuery, pluginObject || {} );

If you want to go more in depth and do things really the right way, you'll have to use method chaining. (There's still room for improvement left).

( function( $, plugin ) {
    "use strict";

    $.ajax( {
        url : plugin.ajaxURl,
        data : {
            // other data
        },
    } )
        .done( function( data ) {
            // Handles successful responses only
        } )
        .fail( function( reason ) {
            // Handles errors only
            console.debug( reason );
        } )
        .always( function( data, textStatus, response ) {
            // If you want to manually separate stuff
            // response becomes errorThrown/reason OR jqXHR in case of success
        } )
        .then( function( data, textStatus, response ) {
            // In case your working with a deferred.promise, use this method
            // Again, you'll have to manually separates success/error
        } );
} )( jQuery, pluginObject || {} );

Note: For better examples of the wrapper around the callback, take a look at commonjs or AMD and their difference.

Waiting for other AJAX responses

The interesting - and most powerful part of the whole jQuery (and other libararies) AJAX handling - question is how to wait until A is finished to then start B and its processing. The answer is "deferred" loading and "promises".

I'll add a quick example. You should maybe think about building and object and separating stuff by appending it via this. to the object, but for an example the following should be enough:

Example (A) This basically like I do it. You'll have to fill the bits your own.

( function( $, plugin ) {
    "use strict";

    $.when(
        $.ajax( {
            url :  pluginURl,
            data : { /* ... */ }
        } )
           .done( function( data ) {
                // 2nd call finished
           } )
           .fail( function( reason ) {
               console.info( reason );
           } );
        )
        // Again, you could leverage .done() as well. See jQuery docs.
        .then( 
            // Success
            function( response ) {
                // Has been successful
                // In case of more then one request, both have to be successful
            },
            // Fail
            function( resons ) {
                // Has thrown an error
                // in case of multiple errors, it throws the first one
            },
        );
} )( jQuery, pluginObject || {} );

Example (B) I never tried it like this, but it should work as well. Easier to read, but I like $.when() resolved promises more.

( function( $, plugin ) {
    "use strict";

    $.ajax( {
        url : plugin.ajaxURl,
        data : {
            // other data
        }
    } )
        .done( function( data ) {
            // Handles successful responses only
        } )
        .fail( function( reason ) {
            console.info( reason );
        } )
        // Promise finished:
        .then( function( data ) {
            $.ajax( {
                url :  pluginURl,
                data : { /* ... */ }
            } )
                .done( function( data ) {
                    // 2nd call finished
                } )
                .fail( function( reason ) {
                    console.info( reason );
                } );
        } );
} )( jQuery, pluginObject || {} );

If you want to get even more in depth, read the Docs about deferred and then.

share|improve this answer
    
actually I am not using any plugin. Simple wp ajax call. Regarding server delay issue- Firebug shows ajax request complete with no received data. Let me go through your answer deeply. –  Istiaque Ahmed Oct 14 '13 at 14:32
    
@IstiaqueAhmed Above description isn't meant to be some plugin. Just the base to write your own plugin (or, in case you don't care about separation of concerns, your own theme). –  kaiser Oct 14 '13 at 14:38
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.