jsGrid LoadData - done() is not called after ajax() - javascript

Consider the following code sample from my grid controller:
loadData: function (filter) {
var data = $.Deferred(); // This line is hit.
var rsp = null;
$.ajax({
type: 'GET',
contentType: 'application/json: charset=utf-8',
url: loadRoute,
data: filter,
dataType: 'JSON'
}).done(function (response)
{
// This function is never invoked.
debugger;
rsp = response;
data.resolve(response);
});
return data.promise();
},
When I debug this code, a breakpoint set on the first line of loadData is successfully hit; however, the debugger statement inside done is never hit. I can't see any obvious reason why.
Can anyone see what I am doing wrong here?
As far as I can tell this method must return a promise, which I am doing. Further, I have to resolve the data returned from the AJAX call to unpack it, which I am also doing (provided I can hit done).
FWIW, the server side code is invoked (loadUrl) and returns without error. But because I can't get into done, I can't inspect the data.

Related

AJAX delaying the execution of next lines

Given the following code, can anyone help me understand why the first alert is executed after the second one? I believe this happens because ajax has a small delay untill it fetches the data, correct me if i am wrong.Thanks in advance.
Javascript code:
window.onload = function() {
arry = new Array();
jQuery.ajax({
type: "GET",
url: "index.php?op=17&id=##postID##&action=fetch",
dataType: "text",
success: function(response){
var e = response;
console.log(JSON.parse(e));
arry = JSON.parse(e)
alert(e); //1st alert
}
});
alert("test") //2nd alert
}
The first "A" in AJAX stands for asynchronous. That means that it is not blocking in your code, so the alert('test') is called immediately after your AJAX request, whereas alert(e) is only called once the AJAX request has received a successful response from the server.
The 'small delay' that you mention is not such, but rather the time it takes for the server to execute whatever code and return a response.
If you absolutely need the request to be handled synchronously, you can pass the async property to the AJAX call as follows:
window.onload = function() {
var arry = [ ];
jQuery.ajax({
type: "GET",
url: "index.php?op=17&id=##postID##&action=fetch",
dataType: "json",
async: false
}).done(function(response) {
arry = response
alert(response); //1st alert
});
alert("test") //2nd alert
}
Notice that I have updated the code somewhat to use the done() promise. Also, specifying dataType: "json" negates the need to call JSON.parse() on the response text.
yous first array is inside the success event of the AJAX call which (the success function) gets registered, skipped and called back only when the response of the ajax call is ready..

store result ajax into variable not working

I'm trying to store ajax result into variable. When I use console.log it gives my html tag that I wanted, But when I trying set into global variable it said undifined.
How I can store ajax result into global variable
var result;
$.ajax({
url: "person.html",
success: function(data){
//result=data;
console.log(data);
}
});
//console.log(result);
Ajax is asynchronous, meaning that the code to find out what result IS is running at the same time that the console log of result, which is why you're getting undefined, because result hasn't been set by the time the value is being console logged.
The only way I know of to console log the result would be to either do it within the ajax success function or to have the ajax success function call a subsequent function that contains the console log. It's the only way to be sure that a value has been returned before you console log it.
Examples:
EXAMPLE 1:
var result;
$.ajax({
url: "person.html",
success: function(data){
result=data;
console.log(result);
//Note that in this instance using the variable 'result' is redundant, as you could simply console.log data like you're already doing.
}
});
EXAMPLE 2:
var result;
$.ajax({
url: "person.html",
success: function(data){
result=data;
subsequentFunction(result);
}
});
function subsequentFunction(result){
console.log(result)
}
// Note that if you're doing something simple with result that this could be a bit long winded and unnecessary.
It all depends on how much you're wanting to do with the result as to which option would be better.
Note: There is also a property of an ajax call called 'async' that you can set to false which forces it to be synchronous, but this is generally considered a bad idea as it will prevent any other code from running until the result is returned and locking the browser.
$.ajax returns a promise, meaning that your code KNOWS it's going to receive a response, but because it's dependent on an external source, it doesn't know when this response will come in.
http://www.htmlgoodies.com/beyond/javascript/making-promises-with-jquery-deferred.html
See above link for more information on the subject.
ajax requests are async so your console.log(result) is running before getting response of your request. you should do something like this
var result;
$.ajax({
url: "person.html",
success: callback(data)
});
function callback (data){
result=data;
console.log(result);
}
You will not see anything beacuse the data is not populated yet. In your specific case you actually need to wait for the response. You can achieve it by using the following snippet.
$(document).ready(function(){
var data = $.parseJSON($.ajax({
url: 'person.html',
dataType: "json",
async: false
}).responseText);
var myProp = data.property; // Here you can access your data items
});
Another approach should be like you can push your data in an array and can access it in another function like this:
var result =[];
$(document).ready(function()
{
$.ajax({
url: 'person.html',
async:true,
dataType: "json",
success: function(data)
{
result.push(data);
}
});
});
NewFunction()
{
console.log(result);
}

Wait for Async ajax to complete before moving onto other code?

I know this has been asked, probably, a million times, but for the life of me I cannot get anything to work.
I have a UI wizard control that on the "changed" event validates the model. If the model is not valid, it doe not allow the user to move forward in the wizard. I have tired using the $.when().done() feature in jquery, but my code still passes through before making sure the model is valid. The reason for calling an async ajax request is I do not want the UI to lock up so I can show some sort of progress indicator. I had set the async property to false, but my UI indicator would never show up. Here is an example of what my code is doing:
//the change event that is called when the user clicks 'next' on the wizard:
wizard.on('change', function (e, data) {
var isValid = $.validate({
"Model": [The_UI_MODEL],
"Url": [URL_To_Server_Validation],
"Async": true, //tells ajax request to send as async
});
//Tells the wizard not to move 'next' if the request comes back as not valid
if (data.direction === 'next' && !isValid) {
e.preventDefault();
}
}
//I am using the $.extend method for JQuery to create a function that will validate any model in my system.
validate: function(options) {
//Clear any previous validation errors
$.clearValidations();
var data = $.postJson(options);
//the result is getting returned before the $.postJson(options) finishes
return data.Success;
}
//I created my own method that extends the $.ajax method so I could do other things before /after a request:
postJson: function(options){
...other code for my application
//This is where I want the ajax request to happen and once done return the data coming back
//This is what I have tried, but it is not doing what I thought.
$.when(function(){
return $.ajax({
url: options.Url,
type: 'POST',
cache: false,
async: options.Async,
timeout: options.Timeout,
contentType: 'application/json; charset=utf-8',
dataType: "json",
data: JSON.stringify(options.Model),
error: function(xhr, status, error) {
...do stuff if ajax errors out
},
success: function (data) {
},
});
}).done(function(response){
//looks like i get back the responseText of the request. which is fine, but other posts i have read stated i should be getting back the request itself
...other UI stuff
return response;
})
}
KarelG is absolutely right. You need to refactor your code and do your valdiation check within the success callback of the ajax request.
Something like this...
wizard.on('change', function (e, data) {
$.ajax({
url: [URL_To_Server_Validation],
type: 'POST',
cache: false,
async: true,
contentType: 'application/json; charset=utf-8',
dataType: "json",
data: {"Model": [The_UI_MODEL]},
success: function (response) {
//Tells the wizard not to move 'next' if the request comes back as not valid
if(!response & data.direction === 'next')
{
e.preventDefault();
}
}
});
});
It looks like you're trying to write asynchronous code as if it were synchronous. An asynchronous call such as your $.validate() will return immediately without a result and continue on to the rest of your code. Anything you want to happen when the validate call finishes must be done in a callback function passed to it.
You can use jQuery promises (when, then, done, etc.) or another library such as async.js to help manage the control flow.
Also, this isn't particularly useful now since there's little to no browser support for it yet, but the yield operator plus a library such as Task.js will eventually let us write asynchronous code as if it were synchronous.

Javascript variable returns to original value after i overwrite it [duplicate]

I'm relatively new to JavaScript and I thought I knew how callback functions worked but after a couple of hours of searching the web I still do not understand why my code is not working.
I am making an AJAX request which returns a string array. I'm trying to set this array to a local variable, but it seems to lose it's value as soon as the callback function is executed.
var array;
$.ajax({
type: 'GET',
url: 'include/load_array.php',
dataType: 'json',
success: function(data){
array = data;
},
error: function(jqXHR, textStatus, errorThrown){
alert("Error loading the data");
}
});
console.debug(array);
In the console, array appears as undefined. Can anyone explain to me why this is not being set and how it is possible to set a local variable in a callback function.
The problem here is that console.log executes synchronously while the ajax call executes asynchronously. Hence it runs before the callback completes so it still sees array as undefined because success hasn't run yet. In order to make this work you need to delay the console.log call until after success completes.
$(document).ready(function() {
var array;
var runLog = function() {
console.log(array);
};
$.ajax({
type: 'GET',
url: 'include/load_array.php',
dataType: 'json',
success: function(data){
array = data;
runlog();
}});
});
The first A in ajax is for Asynchronous, which means that by the time you are debugging the array, the result still hasn't been delivered. Array is undefined at the point of displaying it's value. You need to do the console.debug below array = data.
The success function doesn't execute immediately, but only after the HTTP-response arrives. Therefore, array is still undefined at this point. If you want to perform operations on the HTTP-response data, do it from within the success function, or alternatively, define that operation inside of a function and then invoke that function from within the success callback.
Try calling a function to set this variable after your success:
var array;
var goodToProceed = function(myArr) {
console.debug(myArr);
};
$.ajax({
type: 'GET',
url: 'include/load_array.php',
dataType: 'json',
success: function(data){
goodToProceed(data);
},
error: function(jqXHR, textStatus, errorThrown){
alert("Error loading the data");
}
});
AJAX is asynchronous. You are setting the array variable, but not until after that debug executes. Making an AJAX call sends a request but then continues on in the code. At some later point, the request returns and your success or error functions execute.

jQuery $.ajax success must be a callback function?

I've created a wrapper function for jQuery's $.ajax() method so I can pass different dataTypes and post variables - like so:
function doPost(dType, postData, uri){
$.ajax({
url: SITE_URL + uri,
dataType: dType,
data: postData,
success: function(data){
return data;
});
}
The problem I'm having is getting the data (which is always JSON) back out. I've tried setting a var ret before the $.ajax() function call and setting it as ret = data in the success function. Am I being stupid about this? If I don't set a success function, will the $.ajax simply return the data? Or is it just success: return data? Or does success require a callback function to handle the data, which could just be return data?
Well, you are inside a function - take advantage of variable scope ;-)
function doPost(dType, postData, uri) {
var result;
$.ajax({
url: SITE_URL + uri,
dataType: dType,
data: postData,
async: false,
success: function(data){
result = data;
});
return result;
}
This actually works, but I guess the async part is obligatory then... Otherwise the call of $.ajax would return immediately, and result would still be undefined - you would always get undefined as result of your function call.
However, when you make the $.ajax call synchronous, it blocks until the data is received, and you can return the data as result of your own function.
But you have to be clear that when using this method, no other code will be executed until the ajax load finishes!
When you call $.ajax() it creates the request and then moves on to the next thing. It doesn't sit around and wait for the return and block the next lines of code. That means that unless the success callback function can't return the value of data for the doPost function.
If you really want to have a wrapper function then you could do something like this:
function doPost(dType, postData, uri, success){
$.ajax({
url: SITE_URL + uri,
dataType: dType,
data: postData,
success: success
});
}
And define your success handler when you call doPost, but the wrapper function really isn't doing much for you at the point.

Categories