I’m working with a JS API that I access by using POSTs and GETs. It’s for an e-comm platform (Shopify), but I don’t believe this issue is related to the platform.
I’ve been able to write two POST requests that individually perform exactly as needed whether in code, or in the console. However, I simply cannot get them to fire one after the other (the first must complete before the second begins in my case).
The first request is as follows (this clears the cart, and no data needs to be sent, just the URL needs to be POSTed to):
function clearCart(){
$.ajax({
url: '/cart/clear.js',
method: 'POST',
success: function(){
console.log("cleared");
},
error: function(jqXHR, textStatus, errorThrown) {
console.log('jqXHR:');
console.log(jqXHR);
console.log('textStatus:');
console.log(textStatus);
console.log('errorThrown:');
console.log(errorThrown);
}
});
}
The second request is as follows (this adds a certain item and a certain quantity of said item to the cart, then redirects to checkout):
function cartAdd(quantity, id){
$.ajax({
url: '/cart/add.js',
method: 'POST',
data: {
quantity: quantity,
id: id
},
success: function(data){
console.log("added");
window.location.href = '/checkout';
},
error: function(jqXHR, textStatus, errorThrown) {
console.log('jqXHR:');
console.log(jqXHR);
console.log('textStatus:');
console.log(textStatus);
console.log('errorThrown:');
console.log(errorThrown);
}
});
}
The way that I’m chaining them together looks like this (variables are populated correctly):
$.when(
clearCart(),
cartAdd(variantQuantity, variantID)
);
After much testing, I sometimes seem to have the code work correctly (maybe 1/10th of the time) so I’m led to believe it is a timing issue, although I can’t say for certain as I can’t consistently test to those results.
My only real clue is that the functions individually work when I use .done(), but when I use .success(), they return the following:
SyntaxError: Unexpected token :
at eval (<anonymous>)
at jquery-1.10.2.min.js?1013630…:4
at Function.globalEval (jquery-1.10.2.min.js?1013630…:4)
at text script (jquery-1.10.2.min.js?1013630…:6)
at On (jquery-1.10.2.min.js?1013630…:6)
at k (jquery-1.10.2.min.js?1013630…:6)
at XMLHttpRequest.r (jquery-1.10.2.min.js?1013630…:6)
Any help?
Update
I’m actually able to resolve the syntax error by explicitly specifying a datatype of ‘json’. Regardless, the two functions still behave erratically, only working in the right order sometimes.
5
Answers
If your assessment is correct, you can simply make the functions run synchronously in order to ensure that your second function is called only when the first one has executed. Here’s how you could do it:
Note the
async
property that tells the browser to wait for the request to complete before next function is called. You do not need to set this on the second function given that you are not expecting anything to execute after that.Also, I would suggest you use a callback in the first function rather than
async=false
as async tends to hurt user experience.Reference: http://api.jquery.com/jquery.ajax/
No value or jQuery promise is returned from either
clearCart()
orcartAdd()
functions, see Why is value undefined at .then() chained to Promise?.return
the$.ajax()
call, chain.then()
to call second function.The problem of putting
async
option is that this option makes everything hanging until the response.For these cases: at first we call the ajaxes on the
ready
function of page and put them in differentsessionStorage
s and then in our function (which will be out ofready
or at least the function is out ofready
and just call it inready
) we check the values. If they are null we call the function again after a specific time (3s for example) usningsetTimeout
and after a while the values are set and we can use them in our functionExample code:
And by the way, sessionStorage is diffrent for each browser and if the current window is closed you can’t, you have to set it again. If you want to use something like that but have access from all browser window (which your site is open in them) use
localStorage
instead ofsessionStorage
Return promise to make it use like chaining.
Now call function like this
There are other ways instead of using deprecated method “async: false”. As sometimes it may result badly. However, you can use it.
But I would suggest you other ways to achieve this task:
First: Use deferred.then() method
for example if you have two ajax calls:
then just use then method and return second ajax call as promise :
It will result what you expected or chaining of ajax Calls.
Another method is just put the ajax calls inside the success block of ajax.
Both methods will result what you expected and the good thing about them is they are not the deprecated method.