updated UI not showing before sync ajax call - javascript

I Have a 2 JavaScript functions what call one after another. like following.
updateUI(event);
syncCall();
function updateUI(event) {
formSubmitBtn = $(event.target).find('[type=submit]:not(".disabled")');
formSubmitBtn.attr('disabled', 'disabled');
var loadingText = I18n.t('Submitting');
formSubmitBtn.val(loadingText).text(loadingText);
}
function syncCall(){
$.ajax({
async: false,
dataType: 'json',
type: 'GET',
url: '/calls/synccall',
success: function (json) {
userIsSignedIn = json.is_signed_in;
}
});
}
I am updating a UI element before sync ajax call. but UI changes are not showing. When I try to debug the code it works fine.

I can imagine your code is doing something like
var userIsSignedIn;
updateUI(event);
syncCall();
nextThing(userIsSignedIn);
anotherThing();
moreThings();
With a simple change to syncCall - called asyncCall to be not confusing
function asyncCall(cb){
$.ajax({
dataType: 'json',
type: 'GET',
url: '/calls/synccall',
success: function (json) {
cb(json.is_signed_in);
}
});
}
your code re-written:
updateUI(event);
asyncCall(function(userIsSignedIn) {
nextThing(userIsSignedIn);
anotherThing();
moreThings();
});
Note the lack of var userIsSignedIn; required
Really a small change for improved end user experience
a second alternative is to wrap all the code you presented in a function tagged async
async function doThings() {
updateUI(event);
let userIsSignedIn = await ajaxCall(); // see below
nextThing(userIsSignedIn);
anotherThing();
moreThings();
}
and return a Promise from ajaxCall (what was syncCall)
function ajaxCall(){
return $.ajax({
dataType: 'json',
type: 'GET',
url: '/calls/synccall'
}).then(json => json.is_signed_in);
}
Run this through a transpiler (like babel) to produce code that should work on Internet Exploder and similarly "backward" browsers
Summary: In the end you have two choices
Use async:false and have rubbish user experience
embrace asynchrony and write code that befits the 21st century

Call this function beforeSend like as follows
function syncCall(){
$.ajax({
async: false,
dataType: 'json',
type: 'GET',
url: '/calls/synccall',
beforeSend:function(){
updateUI(event);// Call here
}
success: function (json) {
userIsSignedIn = json.is_signed_in;
}
});
}
If above not work try following
updateUI(event);
function updateUI(event) {
formSubmitBtn = $(event.target).find('[type=submit]:not(".disabled")');
formSubmitBtn.attr('disabled', 'disabled');
var loadingText = I18n.t('Submitting');
formSubmitBtn.val(loadingText).text(loadingText);
syncCall();// Try calling here
}
function syncCall(){
$.ajax({
async: false,
dataType: 'json',
type: 'GET',
url: '/calls/synccall',
success: function (json) {
userIsSignedIn = json.is_signed_in;
}
});
}

Related

What is AJAX best practice?

I am trying to learn javascript best practices and I am a bit confused. I have red that best ajax practice is:
function doSomething(arg1, arg2) {
jQuery.ajax({
var urlink = resourceURL
url: urlink,
cache: false,
data : "testData"+arg1,
type: "POST"
}).done(function(data) {
var obj = jQuery.parseJSON(data);
updateHtml1(obj);
updateHtml2(obj);
});
}
and not this way:
function getSomething(arg1, arg2) {
jQuery.ajax({
var urlink = resourceURL
url: urlink,
cache: false,
data : "testData"+arg1,
type: "POST",
success: function(data) {
var obj = jQuery.parseJSON(data);
updateHtml1(obj);
updateHtml2(obj);
}
});
}
I am asking which practice is best and why?
Either way is fine, it's just a difference in using the success callback or a promise, and in this case there is no difference. If you would want to return the result from the function doSomething then you would use the first method so that you can return the promise, as the done method then can be bound outside the function.
Both examples are overly complicated, and the var urlink = resourceURL is placed inside an object literal, so neither would actually work. You should also specify the dataType in the call, then the data will be parsed automatically.
In the first example you don't need an extra function wrapper.
function doSomething(arg1, arg2) {
jQuery.ajax({
url: resourceURL,
cache: false,
data : "testData"+arg1,
type: "POST",
dataType: "json"
}).done(function(data) {
updateHtml1(data);
updateHtml2(data);
});
}
And the second should be:
function getSomething(arg1, arg2) {
jQuery.ajax({
url: resourceURL,
cache: false,
data : "testData"+arg1,
type: "POST",
dataType: "json",
success: function(data) {
updateHtml1(data);
updateHtml2(data);
}
});
}

ajax - return and prevent deferred.then() execution

I have a AJAX request like this:
$.ajax({
type: 'GET',
url: url,
dataType: "json",
success: function(data) {
// ...
callbak(true);
},
})
.then(
function( response ) {
// ...
});
I'd like to run that callback function and so exit from that ajax request in success function and prevent deferred.then() execution.
In my case the callback is fired but after that deferred.then() is also executed and I don't want this to happen.
Any idea?
Thanks
Use a flag like so:
var executeThen = true;
$.ajax({
type: 'GET',
url: url,
dataType: "json",
success: function(data) {
// ...
executeThen = false;
callbak(true);
},
})
.then(function(response) {
if(executeThen){
// ...
}
});

Returning values from Get function of Jquery

Hi I am trying to get a return value from a get function from a jquery Get request on success.
I have tried many ways already but with no success. Two forms which i have tries are:
1)
GetResultOutput = function () {
var outPut = "No Data Found";
var test = test();
return test["outPut"];
}
test = function()
{
outPut = "No Data Found";
**return** $.ajax({
type: "GET",
url: serviceUrl,
dataType: "xml",
success: function (xml) {
outPut = "done";
}
});
}
2)
GetResultOutput = function () {
outPut = "No Data Found";
$.ajax({
type: "GET",
url: serviceUrl,
dataType: "xml",
success: function (xml) {
outPut = "done";
}
});
return outPut;
}
But both of them is not giving me any result..
2nd one outputs me as no data found. and 1st one which is preferred one when googled...results as undefined
Instead of trying to get the output and then process it like:
var output = GetResultOutput();
process(output);
You could pass process as a callback like:
var GetResultOutput = function (callback) {
$.ajax({
type: "GET",
url: serviceUrl,
dataType: "xml",
success: function (xml) {
callback(xml);
}
});
};
// usage:
GetResultOutput(process);
You can also make your ajax call synchronous by using:
$.ajax({
type: "GET",
url: serviceUrl,
async: false,
dataType: "xml",
success: function (xml) {
outPut = "done";
}
});
Ajax request are asynchronous, which means you cannot immediately "return" data from the call. That is why all forms of $.ajax take one or more callbacks to be called when data is received, or an error occurs etc.
Which means your method must look like:
GetResultOutput = function (callback) {
$.ajax({
type: "GET",
url: serviceUrl,
dataType: "xml",
success: callback
});
}
with callback looking like:
function callback(xml)
{
console.log('done: ' + xml);
}

Why can't I do .ajax ( return data; )? jQuery

I'm trying to get my function to return the data it got into another function but it doesn't seem to work? How can I get it to return the data?
function playerid(playername) {
$.ajax({
type: "POST",
url: "fn.php?playerid",
data: "playername="+playername,
success: function(data) {
//$("#test").text(data);
return data;
}
});
}
I want to use it in another function like this
showBids(playerid(ui.item.value));
function showBids(playerid) {
$.ajax({
type: "POST",
url: "poll.php?",
async: true,
dataType: 'json',
timeout: 50000,
data: "playerid="+playerid,
success: function(data) {
//.each(data, function(k ,v) {
//})
//$("#current_high").append(data);
setTimeout("getData()", 1000);
}
});
First of all, your playerid() does not return anything, so what do you want to use? It has only $.ajax() call in it, no return statement (one of the callbacks in $.ajax() has return statement, but see below).
Secondly, JavaScript does some things asynchonously, otherwise every interface element would need to wait to react to user action until the AJAX call returns from the server.
Use event-based approach, by passing callbacks to some functions. Then, after they finish, just call the callbacks passing them the result:
function getplayerid(playername, callback) {
$.ajax({
type: "POST",
url: "fn.php?playerid",
data: "playername="+playername,
success: function(data) {
//$("#test").text(data);
callback(data);
}
});
}
and then use it like that:
getplayerid(ui.item.value, showBids);
(notice function name change since it does not actually return player ID, it gets it and passes it to callback)
You could try to use syncronous Ajax:
function playerid(playername) {
return $.ajax({
type: "POST",
url: "fn.php?playerid",
data: "playername="+playername,
async : false //making Ajax syncronous
}).responseText;
}
Otherwise you need to use showBids function as callback:
function playerid(playername, callback) {
$.ajax({
type: "POST",
url: "fn.php?playerid",
data: "playername="+playername,
success: function(data) {
callback(data);
}
});
}
//Usage
playerid(ui.item.value,showBids);

javascript jquery and using eval

i am currenty using jquery plugin to read a data file (data.html)
data.html has below format
[10,20,30,40,50]
my jquery data request and the javascript to return values is below
function test(){
var result=$.ajax({
url:'data.html',
type:'get',
dataType:'text',
async:false,
cache:false
}).responseText
return result;};
var my=test();
alert(my[0])
i want to get these values in the array format i.e i want my[0] to be value 10, but instead i get "[".
If i use eval function
my=eval(test());
i can get 10, but is there any other better way to store the returned ajax calls into an array instead of string?
Thanks
i tried the below answer and i am bit puzzled, the follow code results in myArray is null (in firebug), but i put async:false then it works. why do i need async:false to store the values into array ? (http://stackoverflow.com/questions/133310/how-can-i-get-jquery-to-perform-a-synchronous-rather-than-asynchronous-ajax-req)
jQuery.extend({getValues: function(url) {
var result = null;
$.ajax({
url: url,
type: 'get',
dataType: 'json',
cache: false,
success: function(data) {result = data;}
});
return result;}});
myArray=$.getValues("data.html");
alert(myArray[1]);
You don't need eval. Just indicate the proper dataType: 'json':
function test() {
return $.ajax({
url: 'data.html',
type: 'get',
dataType: 'json',
async: false,
cache: false
}).responseText;
}
var my = test();
alert(my[0]);
or even better do it asynchronously:
function test() {
$.ajax({
url: 'data.html',
type: 'get',
dataType: 'json',
cache: false,
success: function(result) {
alert(result[0]);
}
});
}
test();
I think jquery $.getScript('data.html',function(){alert("success"+$(this).text())} might be simpler. I have not had time to try it so if I'm on right track, improve this answer, if not I'm happy to learn now...

Categories