Search code examples
javascriptjqueryajaxpluginschaining

jquery plugin - make ajax call chainable


I am trying to write a jquery plugin.

Now, I would like to use an ajax-call in one of the functions of this plugin.

However it should be chainable, meaning in this case that the ajax-call should be executed and only after something was returned, the return should happen.

I tried different things but so far I could not make it so that the second function in the chain is really executed after the return value of the ajax call was retrieved;

In this version (see below) I can use

$(document).createDatabase().message();

So, chaining works. But looking at the console log – the message() function is executed before the ajax-call in createDatabase() is finished.

How can I make it so that

$(document).createDatabase().message();

first returns the output/return of the ajax-call that is inside createDatabase() and only after that message() is executed?

Code:

(function($) {

    $.fn.createDatabase = function(options) {

        // Plugin options defaults
        var settings = $.extend({
            name: 'NA',
            onExit: function() {} // callback function
        }, options);

        $.ajax({
                method: "POST",
                url: "plugin/php/createDatabase.php",
                data: settings
        })
        .done(function(msg) {
             console.log("createDatabase executed with message: " + msg);
             settings.onExit.call();    
        });

      return this;

   };



   $.fn.message = function() {

       console.log('this should appear after the console-log message of createDatabase');
       return this;
   }

}(jQuery)); 

Thank You!


Solution

  • You could do a couple of things, but they are all a bad idea. The reason is that these are two separate jQuery plugins - a plugin should be capable of working on its own. There is no guarantee or reason that somebody won't do .message().createDatabase(). If you need to guarantee the order of execution, then you should use just one plugin. One possible way would be to pass message inside options when you call .createDatabase(options), and then run message when the call is done. Like so

    $(document).createDatabase({
        message: function() {...}
    });
    ...
    var promise = $.ajax({
                method: "POST",
                url: "plugin/php/createDatabase.php",
                data: settings
        })
        .done(function(msg) {
             console.log("createDatabase executed with message: " + msg);
             settings.onExit.call();    
        });
    ...
    if ( settings.message )
        promise.done( settings.message.bind(this) );
    

    I tried different things but so far I could not make it so that the second function in the chain is really executed after the return value of the ajax call was retrieved;

    The second function executes when the first one finishes. The first one finishes with return this, but this happens before the ajax call is done because ajax calls are asynchronous.