Gideon
Gideon

Reputation: 1604

Reusing a JavaScript AJAX call before another AJAX call

I have two buttons that both performs AJAX call:

$("#save").click(function() {
    $.ajax({
        type: "POST",
        url: saveEntryURL,
        data: { id: $("#id").val() },
        success: function(r) {
            ...
        },
        error: function(r) {
            ...
        }
    })
})

$("#tag-as-final").click(function() {
    $.ajax({
        type: "POST",
        url: finalizeEntryURL,
        data: { id: $("#id").val() },
        success: function(r) {
            ...
        },
        error: function(r) {
            ...
        }
    })
})

The requirement is that when the user click the finalize button, the system will first perform a save before actually tagging it as final. To reuse the code attached to the save button, I call the onclick listener of the save button before the actual AJAX call like this:

$("#tag-as-final").click(function() {
    $("#save").click()
    ^^^^^^^^^^^^^^^^^^    
    $.ajax({
        type: "POST",
        url: finalizeEntryURL,

But it will not do "save-and-finalize-after" behavior since both AJAX calls are asynchronous. I need to run one after another, but cannot afford to make the AJAX call of the save button synchronous (I'm doing also a lot of other things while the tagging occurs occurs). I know this would be silly but I'm thinking something similar to...

$("#tag-as-final").click(function() {
    $("#save").click().peformAsyc()
                       ^^^^^^^^^^^^
    $.ajax({
        type: "POST",
        url: finalizeEntryURL,

...that will force it to finish performing first the chained function before continuing, but I know that is not available. Is there any way to do this? My current work-around is placing the same save AJAX function inside the finalize AJAX function, though it doesn't allow me to code DRY (Don't Repeat Yourself):

$("#tag-as-final").click(function() {
    $.ajax({
        type: "POST",
        url: saveEntryURL,
        data: { id: $("#id").val() },
        success: function(r) {
            ...
            $.ajax({
                type: "POST",
                url: finalizeEntryURL,
                data: { id: $("#id").val() },
                success: function(r) {
                    ...
                },
                error: function(r) {
                    ...
                }
            })
        },
        error: function(r) {
            ...
        }
    })
})

Upvotes: 1

Views: 445

Answers (1)

MinusFour
MinusFour

Reputation: 14423

It's pretty simple, you are better using jquery "promises". Like so:

var generalSettings = { }; //Settings for AJAX call.
var jqXHR = $.ajax(generalSettings); //Do AJAX call.
generalSettings.data = 'newdata'; //update generalSettings
jqXHR.done(function(data){
   $.ajax(generalSettings); //New Petition with updated settings.
});

This is using ES6 promises and jQuery promises:

function doAjaxAsPromise(settings){
    return new Promise(function(resolve){
        var jqXHR = $.ajax(settings);
        jqXHR.done(function(data){
            resolve(data);
        });
    });
}

var settings = { };
var petition = doAjaxAsPromise(settings);
var secondpetition = petition.then(function(data){
    //work with data
    //new settings
    var settings = { };
    return doAjaxAsPromise(settings);
});
var thirdpetition = secondpetition.then(function(data){
    //work with data
    //new settings
    var settings = { };
    return doAjaxAsPromise(settings);
});
//If needed to reuse settings object outside promise scope:
//var settings = Object.create(settings);

Some other nice thing you can do for code reuse:

function save(settings) {
    var prom = doAjaxAsPromise(settings);
    return prom.then(function(data){
        //do something with your data.
    });
}

function tagAsFinal(savedPromise, settings){
   return savedPromised.then(function(){
       var prom = doAjaxAsPromise(settings);
       return prom.then(function(data){
          //work with data;
       });
   });
}

$('save').on('click', function(){
  save(settings); //settings = $.ajax settings.
});

$('tagAsFinal').on('click', function(){
  var generalSettings = { };
  var settingsone = Object.create(generalSettings);
  var settingstwo = Object.create(generalSettings);
  var saved = save(settingsone); //$.ajax settings.
  tagAsFinal(saved, settingstwo);
});
//Can still be reduced.

Upvotes: 2

Related Questions