global variable when using ajax() [duplicate] - javascript

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 7 years ago.
$.ajax({
type: "POST",
url:"example.com",
success: function (data) {
myData = data;
},
error: function (response) {
}
//here json = myData;
});
I have to do json = myData which is outside the callback function of ajax() to make it as a global variable, I wonder is this a good practice? How else can I use the data of my ajax callback?

Why do you want to break the asynchronous nature that Ajax was literally designed to have? "Problems" like these have been repeatedly asked on StackOverflow. But the one key thing they forget is that Ajax was designed to be asynchronous, and by trying to use the data outside of the function you're somewhat breaking that rule.
TL;DR: Ajax was designed to be asynchronous, lets keep it that way.
If you want to keep a neat structure, define a handler.
function handler(data) {
// Handle data
console.log(data)
}
$.ajax({
url: "http://localhost",
type: "POST",
data: {'example':true},
success:handler
});
I do not advise this method, read the above on why not.
If you truly need to perform a synchronous Ajax request (sjax? Lol, jQuery does provide a feature to "turn off the asynchronous nature", using the async: false in the object appears to solve that. Here is an example:
var outterData;
$.ajax({
async: false,
url: "/echo/json/",
data: {testing:true},
success: function(data){
outterData = data;
}
});
console.log(outterData);
As you can see, async: false was included in this. And it appears to work fine, based on this JSFiddle a built.
But remember, I don't advise you take away the asynchronous nature of Ajax (it's in the name, for crying out loud). But if you must.

Related

Success data returns null from AJAX GET type [duplicate]

This question already has answers here:
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference
(7 answers)
How do I return the response from an asynchronous call?
(41 answers)
Closed 3 years ago.
I am using the following codes to get success data into a variable:
var compdet = null;
$.ajax({
url: uri2 + "/" + $("#textbox_id").val(),
type: "GET",
cache: false,
success: function (data) {
compdet = data;
}
});
And to check if my var compdet has value in it, I added:
console.log(compdet);
Sadly, it returns JUST null. So I tried putting the console.log into
success: function (data) { console.log(data); }
And it returns the output that I want to see. Anyone who can explain this to me?
I realized something here. You can actually make Javascript function async and await AJAX calls.
For example:
async function func_name() {
await $.ajax({
// some codes here
});
}
JavaScript execution is synchronous but AJAX is asynchronous. If you have any code after AJAX it might execute before completing the AJAX. That's why you are getting the value null.
In this scenario you can execute your next code stuff inside success() callback or call another method to execute the next code chunk.
An example with method call:
function next(compdet) {
// code stuff
}
$.ajax({
url: uri2 + "/" + $("#textbox_id").val(),
type: "GET",
cache: false,
success: function (data) {
next(data)
}
});
See the difference between synchronous vs asynchronous.

Javascript / jQuery from async: false to async: true and still get data from outside [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 6 years ago.
I have a few functions that grab data using ajax and I can then get the result data from outside the function when needed.
Here is one example:
function myfunction() {
jQuery.ajax({
url: someurl
method: 'GET',
async: false,
success: function(result) {
myresult = result;
}
});
return myresult;
};
And this from outside I get the data like this:
myvar = myfunction();
Doing it this way I am able to get the data outside the function.
I have searched google and stackoverflow and I still can't understand it so I thought adding a function that I'm already using might help me understand better how to do this.
How can I convert this code so that when I set async to true I'm able to get the data from outside the function?
How can I convert this code so that when I set async to true I'm able to get the data from outside the function?
Simple answer, don't. You're approaching the problem in the wrong way.
Instead of trying to get data available outside the function, you could provide a callback function which the data should be passed to:
function myfunction(callback) {
$.ajax({
url: someurl
method: 'GET',
success: callback
});
};
myfunction(function(data) {
// work with the data retrieved from the async request here...
console.log(data);
});
Note: this pattern is a little redundant in this example as you could just give the anonymous function directly to the success property. In a real scenario you'd probably want to execute some actual generic logic in the success handler before calling the provided callback function.
Alternatively you could return the deferred object from the jQuery AJAX request and then use a done() handler to be executed when the object is resolved:
function myfunction() {
return $.ajax({
url: someurl
method: 'GET'
});
};
myfunction().done(function(data) {
// work with the data retrieved from the async request here...
console.log(data);
});
In either case the logic to follow is that the data from the request should be provided to the required function instead of being made globally available.

$.ajax success function wait

Due to the (my perceived) nature of the $.ajax GET I'm not sure what I'm looking for is possible in this method, but thought I should ask as it's causing me some trouble. I am in no way an expert on JS, apologies if this is obvious, the title is poor, couldn't think of a different way to say it.
What I'm doing - using $.ajax to get values from the back-end API functions (these work). In the success property I'm using an anonymous function to pass more data across that would not otherwise be brought back. When stepping through the console breakpoints in the Chrome console the success function is often skipped as it's not brought back quick enough.
What I would like - in the example below, I don't want getStuff to complete, before its success DoSomething has returned, as I'm missing loads of data from the API which I need to pass through to DoSomething - is this possible to achieve?
Example
function getStuff(id, hid) {
$.ajax({
type: "GET",
url: "/api/GetMyStuff/" + id,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (vData) {
DoSomething(vData, id, hid); // not always being hit
}
});
}
You could use the async option and set it to false to get a synchronous call:
function getStuff(id, hid) {
$.ajax({
type: "GET",
url: "/api/GetMyStuff/" + id,
contentType: "application/json; charset=utf-8",
dataType: "json",
async: false, // HERE
success: function (vData) {
DoSomething(vData, id, hid); // not always being hit
}
});
}
But that is not a good way to do ajax request, you should rethink your code organization (like giving a callback function to your getStuff method and calling it in the success callback).
What you are trying to do is impossible. Asynchronicity is "leaky", meaning that any asynchronous action requiring a callback (e.g., $.ajax()) necessarily forces asynchronous control flow all the way up the call chain.
Please note that in the near future (thanks to async/await in ES7), this situation gets a little better. The asynchronicity is still leaky, but the new keywords make the refactoring scenario a little easier than hand-jamming callbacks everywhere.

Accessing JSON string Outside of Jquery Ajax Call

I am wondering is these is any way to access the results of a jquery ajax call in the form a traditional var set to function fashion. For example consider:
function getPoints(){
//An array of JSON objects
var Points;
$.ajax({
url: "js/retrievePointsDataJson.php",
dataType:'json',
type: 'POST',
}).done(function(data){
//console.log(data);
Points.append(data);
});
console.log(Points);
return Points;
}
The commented out console.log show the array of json objects whereas the outer one does not. Now, i have tries this:
var Points = $.ajax({ ...});
And i see the response text within a larger object, but am unsure how to access the responseText. console.log(Points.responseText) yields an undefined variable.
Is this possible with this approach? Here is another question that received a check mark with a similar issue.
I have another solutions, which is the encapsulate my code within the done() function and i will have access to all my data. I was just curious if what i am attempting to do is even doable.
Thank you.
yes it is possible, however, you must wait for the request to be complete before doing so. However, since you can't effectively force the return to wait until the data exists, you're only options are to return a deferred object instead, or re-write the function in such a way that allows it to accept a callback.
function getPoints(){
return $.ajax({
url: "js/retrievePointsDataJson.php",
dataType:'json',
type: 'POST'
});
}
getPoints().done(function(data){
console.log(data);
});
or
function getPoints(callback){
return $.ajax({
url: "js/retrievePointsDataJson.php",
dataType:'json',
type: 'POST',
success: callback
});
}
getPoints(function(data){
console.log(data);
});
Because the Ajax call is done asynchronously you shouldn't return it from the outside function. This would require that you somehow block until the asynchronous call completes. Instead you could pass in a callback function to the getPoints function that will handle the logic of using the points.
function getPoints(callback){
$.ajax({
url: "js/retrievePointsDataJson.php",
dataType:'json',
type: 'POST',
}).done(function(data){
callback(data);
});
}
The asynchronous nature of ajax can make things harder if your used to imperative programming, but it will make your user interface much more responsive.
The log you're calling in the outer function is working with an undefined variable because the function is asynchronous. You can't return it from getPoints because it won't have finished. Any work with the Points variable needs to happen inside the callback (the function passed to done).

$.ajax Deferred object

These two codes (1)(2) seems to work in the same manner to me.
My questions are:
1) Are these two codes equivalent?
2) If yes why? If not what should I prefer and why?
(1)
$.ajax({
url: backendRouter.generate('feedback_send'),
type: 'POST',
dataType: 'json',
data: data
success: callback,
done: function () {
// some code
}
});
(2)
$.ajax({
url: backendRouter.generate('feedback_send'),
type: 'POST',
dataType: 'json',
data: data
success: callback
}).done(function () {
// some code
});
Yes, the two codes are equivalent, except that (by mistake?) you've left success: callback in the latter.
However IMHO the latter is preferred as deferred objects are far more flexible than supplying a callback directly to $.ajax.
In particular, using deferred objects allows for much better separation of logic and responsibility between initiating the AJAX call and the processing of the results of that call. Also, some of the AJAX helper functions don't support an error callback. If I write:
function doAjax() {
return $.get(...);
}
I can then attach arbitrary numbers of done and fail handlers to the result of that function call, without ever having to pass those handlers into the doAjax function.
I can also combine the returned promise() object with other promises using $.when(), $.pipe(), etc, for very powerful synchronisation between multiple asynchronous events (including other AJAX calls, timers, animations, etc). I can't do that using success:

Categories

Resources