can jquery $.getJSON's JSON data be assignable to other variable? - javascript

I'm using jQuery $.getJSON(..) to get some json.
The passed value shows me "undefined".
Is there a way to do that?
getTopMenuJson : function(currentPage) {
if(currentPage == null) currentPage = 1;
var retJSON;
$.getJSON(
requestURLs.topMenuJson,
{
'ITEM_PER_PAGE' : TopMenuHandler.ITEM_PER_PAGE,
'CURRENT_PAGE' : currentPage
},
function(JSON) {
//alert(JSON); **<--This gives me result (Object)**
retJSON = JSON;
}
);
**alert(retJSON); //<!-- This doesn't, but Undefined**
},

It doesn't and it shouldn't as getJSON is internally doing an AJAX call, the first A in AJAX stands for Asynchronous, it simply means that the script execution won't wait until your success function is called.
You could instead use $.ajax and pass in async: false to one of its options to make sure that your script waits for the ajax call to be finished, but be aware that doing that would freeze the browser / tab until your AJAX call is finished.
$.ajax({
url: requestURLs.topMenuJson,
dataType: 'json',
data:
{
'ITEM_PER_PAGE' : TopMenuHandler.ITEM_PER_PAGE,
'CURRENT_PAGE' : currentPage
},
success: function(JSON) {
//alert(JSON); **<--This gives me result (Object)**
// this won't work without async:false
// as the execution of script won't wait until this function
// is finished
retJSON = JSON;
},
async: false
});
http://api.jquery.com/jQuery.ajax/
async Default: true By default, all requests are sent
asynchronously (i.e. this is set to true by default). If you need
synchronous requests, set this option to false. Cross-domain requests
and dataType: "jsonp" requests do not support synchronous operation.
Note that synchronous requests may temporarily lock the browser,
disabling any actions while the request is active.

Related

To check if ajax call is synchronous or asynchronous in Browser Dev Tools

Is there a way to confirm whether a particular ajax request in async or sync in Browser Dev Tools like Chrome Developer Tools or Firebug.
For ajax request HTTP Request Header does not indicate whether its sync or async.
X-Requested-With:XMLHttpRequest
no you cant do that but you can run this in console or add this to your code
XMLHttpRequest.prototype.open = (function(open){
return function(method, url, async, user, password) {
console.log("xhr call: "+url +"isAsync: "+async);
open.apply(this, arguments);
};
})(XMLHttpRequest.prototype.open);
it logs the infomation :D hope its helpful
I don't know if you are still looking for an answer but I hope this will help someone!
In chrome browser navigate to rightClick/inspect/networkTab/xhr? move the cursor to the time where your requests are processed as shown in below pic:
THIS IS MY ASYNC CODE(default ajax)
`$.ajax({
type: "GET",
contentType: "application/json", // data type of request
url: //url,
data: //data,
dataType: "json", // data type of response
success: function (result) {
// some code here
}
});`
I was making a series of ajax calls to the localhost and each call was linked to the previous call's response. But I got wrong outputs because all the ajax requests were being sent at almost the same time and the responses(blue in color) which should have been received serially were disordered. The timing diagram below shows the issue perfectly(look at the waterfall tab).
THIS IS MY CODE FOR SYNC CALLS(async: false in ajax)
$.ajax({
async: false,
type: "GET",
contentType: "application/json", // data type of request
url: //url,
data: //data,
dataType: "json", // data type of response
success: function (result) {
// some code here
}
});
Now how to know if async: false is working?
You can see that the timings of ajax calls in async mode are overlapping each other and also the timings for calls in sync mode(async: false) are distinctively separate thus proving that sync calls [async: false] are working fine. If the timings still overlap then sync calls are likely not working, unlike my case.
All ajax requests are asynchronous others wise if its specified to be synchronous hence why they call it Asynchronous JavaScript and XML (AJAX). To make an ajax request synchronous you would have to pass in false inside the open method of an XMLHTTPRequest object like this
var xhr = new XMLHttPRequest();
xhr.open("POST", "file to get.php", false);
The third parameter specifies it as synchronous but it defaults to true

Issue to invoke jquery ajax within the another ajax success

I have the following code within the ajax success function.
$.each(data,function(index,element){
$.ajax({
type: 'GET',
url: "http://192.168.1.56/SampleAjaxCall/sample.svc/sampleFunciton",
contentType: 'application/json; charset=utf-8',
dataType: 'jsonp',
async: false,
success:function(response){
alert("Success !"); // invokes after the loop
}
});
alert("After the ajax call"); // invokes first
});
First i am getting this alert message After the ajax call. after the loop end i am getting this alert message alert("Success !"). So the ajax is invoked after the loop end. So i need to invoke the ajax first. How to achieve this scenario.
Actually, your ajax call is in fact invoked before the second alert message ("After the ajax call"). But, as AJAX stands for Asynchronous etc. etc, while the ajax request is being processed, the rest of the script is executed already. So if you want the code being executed after the ajax call, wrap it in a function, and call that function in the success block (or just move the code into the success callback). Example:
var after_call_func = function() {
alert("After the ajax call");
};
$.each(data,function(index,element){
$.ajax({
// your ajax configuration
success:function(response){
alert("Success !");
after_call_func(); // call the function when ajax is complete
}
});
});
EDIT
I now notice you have the async option set to false, which is most probably why you'd expect the alert to execute AFTER the ajax call in the first place... But, as the jQuery documentation tells us:
Cross-domain requests and dataType: "jsonp" requests do not support synchronous operation.
And it looks like you have both... So either don't use a jsonp datatype nor a cross-domain request, or wrap the code to be executed after the ajax call in the success block, as in the example above.
According to jQuery.ajax docs, dataType: "jsonp" requests do not support synchronous operation, so async: false is not going to work. You need to do it as giorgio describes.

$.ajax with setTimeout synchronous or asynchronous? total performance?

I have seen a code for some chat system which says some thing like below to get the chat messages. I have seen that AJAX is asynchronous. setTimeout here is refreshing the chatlog periodically. So on the whole is it asynchronous communication? $.ajax is synchronous or asynchronous? what is its significance here????
http://net.tutsplus.com/tutorials/javascript-ajax/how-to-create-a-simple-web-based-chat-application/
Asynchrounous communication means the server has to send the data to client if there is any new data without the client bugging the server. Isn't it? Please give me a detailed explanation of what's going on below ....... Any better solution how chatlog can be updated automatically with jquery-ajax
if we are checking every x seconds and reloading the whole window again, what is the need to use $.ajax here? just making code complex .... what is the difference between using just php-sql request to the database and setimeout .... cost of the first case: the whole chat is reloaded over and over+ajax call, cost of the second case: whole chat is loaded over and over ... so i don't understand what is the benefit of using ajax according to performance .... in fact i see the later is better...... Isn't it???
function updateMsg()
{
$.ajax({
url:"db.php",
type:"POST",
success:function(data){
}
});
setTimeout("updateMsg()",7000);
}
You can use async param. async param determines: is request synchronous or asynchronous
$.ajax({
url:"db.php",
type:"POST",
async: true, // async: false
By default is async :
async (default: true) Type: Boolean By default, all requests are sent
asynchronously (i.e. this is set to true by default). If you need
synchronous requests, set this option to false. Cross-domain requests
and dataType: "jsonp" requests do not support synchronous operation.
Note that synchronous requests may temporarily lock the browser,
disabling any actions while the request is active. As of jQuery 1.8,
the use of async: false with jqXHR ($.Deferred) is deprecated; you
must use the success/error/complete callback options instead of the
corresponding methods of the jqXHR object such as jqXHR.done() or the
deprecated jqXHR.success().
function updateMsg() {
$.ajax({
url: "db.php",
type: "POST",
async: true, //or false
success: function (data) {}
});
}

Is this a scope issue in JavaScript / JQuery? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Is it posible to use ajax respone outside of it?
I've created the following JavaScript routine that goes to a WCF oData service and gets some data. In the success element I get the results into the results variable and alert them - I see that there are objects returned. When I run the second alert, outside of the ajax call and before returning the results, the results variable is "undefined".
Can anyone please tell me where I'm going wrong?
function retrieveJsonpODataSet(baseUrl, query)
{
var oDataUrl = baseUrl + "?$format=json&$callback=?";
var results;
$.ajax(
{
url: oDataUrl,
contentType: 'application/json; charset=utf-8',
type: 'GET',
dataType: 'jsonp',
async: false,
success:
function (data, textStatus, xhr)
{
results = data.d;
alert(results); // This shows the results
},
error:
function (xhr, textStatus, errorThrown)
{
alert("Query failed.\n\n" + oDataUrl + "\n\n" + errorThrown);
results = null;
}
});
alert(results); // This shows "undefined"
return results;
}
Please ignore the query parameter - I've not finished the routine yet.
EDIT
Initially I had no async:false in the ajax call. I've added that now but it doesn't fix the problem.
The ajax call is an asynchronous operation. It fires and your code does not stop at it. So results is returned which at that point is undefined. What you need to do is to pass callback to the function.
function retrieveJsonpODataSet(baseUrl, query, callback) {
/* some code */
$.ajax({
/* some settings */
success: function(res) {
/* some code */
callback(results);
}
});
}
Now you use it like this
retrieveJsonpODataSet(baseUrl, query, function(res) {
/* Hurray, I have result now in res variable! */
});
DO NOT USE async: false OPTION! It blocks ALL scripts untill the call finishes... and what if it does not finish at all?? You will be blocked forever.
EDIT
I've missed that the request is JSONP. In that case async: false won't even work (it does not work for cross-domain requests and JSONP). So you have to use callbacks anyway.
A fellow Richard!
This isn't a scope issue, but more of an execution one. Both the success and error options are event handlers, and run asynchronously (hence it being called AJAX). This essentially means that the alert(results) and return results can, and likely will, get executed before the success or error events are triggered.
Your ajax is async, so the alert executes before the ajax completes. You need to set the ajax call async property to false in order for script to halt the execution until ajax request is made & processed.
However, jQuery docs says:
async
Default: true
By default, all requests are sent asynchronously (i.e. this is set to true by default). If you need synchronous requests, set this option to false. Cross-domain requests and dataType: "jsonp" requests do not support synchronous operation. Note that synchronous requests may temporarily lock the browser, disabling any actions while the request is active. As of jQuery 1.8, the use of async: false is deprecated.
AJAX request are sent, without the script waiting for a response, that's what Dave Newton means by A-synchronus, put the alert inside the success callback function, and you'll see what the actual response is.
alternatively, you can specify the async property, and set it to false, to force your script to wait for the response, before continuing.

How can i stop ajax request (don't wait untill response come)?

If I use Ajax to send request and this request take long time ..... if I want to send anther request what should I do?
the current behaviour the second request (I did) waiting until the first request get with response.
NOTE :
i want to do this behaviour on whole application (any new request execute immediately not wait the old one to be finished firstly)
My application using (Ajax + PHP + jQuery + Symfony)
Assume that is the first request take long time:
$.ajax
({
type: "GET",
url: url1,
success: function (html)
{
// do some thing
}
});
In any time I want this request to execute and terminate the first one.
$.ajax
({
type: "POST",
url: url,
success: function (html)
{
// do some thing else
}
});
var xhrReq;
xhrReq = $.ajax(...);
// then if you want to stop the rqest and exit use :
xhrReq.abort();
It’s sort of a manual process, but you can add a global xhr object and test it on each request. If the readystate is "loading", abort it:
var xhr;
var loadUrl = function(url) {
if ( xhr && xhr.readyState > 0 && xhr.readyState < 4 ) {
// there is a request in the pipe, abort
xhr.abort();
}
xhr = $.get(url, function() {
console.log('success', this);
});
};
loadUrl('/ajax/');
The XMLHttpRequest object has an abort function. You can use setTimeout to abort a request that is taking too long.
EDIT: In the case you do not want to use a timer, and a new event occurs that should abort the prior request, then the event handler should do the following
if(!this.request) return; // request contains the XMLHttpRequest
this.request.onreadystatechange = function() {};
if(this.request.readyState != 4) {
this.request.abort();
}
Then after that you can create the new XMLHttpRequest object.
I have been working on this many ways and I feel I found a working solution. I had a caching process that was causing a page to hang until done (average 5 seconds). Yes this is better suited as a CRON job, but I needed to create caching process for the user without knowing the environment they are using for my CMS.
What I had done:
Create the call within a variable and then remove it by a hard delete. By deleting this it seems to be removing the wait. This "hack" seemed to pull the wait from 5 second average to a 325ms wait.
var ignore = $.ajax({
url:something/here.php,
type: "GET",
url: url1,
success: function(){}
});
delete ignore;
Defining the ajax request variable:
var xhr;
Making the ajax call:
xhr = $.ajax(...);
Aborting the ajax call:
xhr.abort();
Browser allows you to handle only limited amount of requests to same host at time (2 or 3 as I remember, depending on browser).
Workaround on requests count is to make fake domains - like img1.domain.com, img2.domain.com, etc. leading to the same host and randomly use them in requests. Then you can just make requests you need. Domains count should be chosen depending on requests quantity in order to keep in bounds - 2 requests per domain. Otherwise 3rd request will wait until one of active finishes.
It allows you to receive responses from all your requests.
For example, Google uses it to make images load faster.
EDIT:
Example: you have http://yourhost.com/ and alias http://alias.yourhost.com which points to the same place.
Then:
$.ajax
({
type: "GET",
url: 'http://yourhost.com/somescript.php',
success: function (html)
{
// do some thing
}
});
and then
$.ajax
({
type: "POST",
url: 'http://alias.yourhost.com/somescript2.php',
success: function (html)
{
// do some thing else
}
});

Categories

Resources