how do i set a js global variable to a json result set in the onload event?
var global = [];
$.getJSON("<%: Url.Action("myUrl", "con") %>/",
function(data) {
$.each(data, function(key, val) {
global.push(val);
});
});
global does not have a value set on load, i need to access it outside the json call...
You again. Maybe try
var result;
$.ajax({
url: '<%: Url.Action("myUrl", "con") %>/',
dataType: 'json',
async: false,
success: function(data) {
result = data;
}
});
// process result here
You don't need to set global to an array. Just assign the value.
var global = null;
$.getJSON("<%: Url.Action("myUrl", "con") %>/",
function(data) {
$.each(data, function(key, val) {
global = val;
});
});
That code should work just fine. (Live copy) Sounds like there's a problem with the ajax call not returning the data in the form you expect.
As #marc (indirectly) points, you have to understand the nature of the ajax call, and event model.
The ajax call is executed as soon as the JS file is parsed, byt result is returned asynchronously. So, your code timeline would look like
00 set global = []
01 AJAX call /someurl/ -------------------\
02 check global /* it's empty */ \
03 do something else [process AJAX call on server, send result]
... /
42 AJAX call is completed <----------------/
43 call success ----------------------------------> global.push(result)
44 at this point of time you can access global
This is a timeline, not the execution order. The time between the AJAX call and the response could be arbitrary, including the case of timeout or server-side error
So, what should you do?
1) the normal solurtion for JS - a callback, the success function you already have could either
1.1) set global and call the other function, or
1.2) do the desired actions with data
2) event - better if you suppose to use the data in multiple parts of the code, read for jQuery events mechanism
3) synchronous call, as #marc suggests - this should be avoided in 99% of cases. The only case I know when itt might be needed is when you have to requst for mandatory data from the 3rd party source, and even in this case you could do it on server (though at least synchronous AJAX is acceptable)
Related
I'm using AJAX to parse json, everything works fine although when I try to call a function where I pass on the index value of the loop and then the funcion pushes this value into the Global array, It seems like it's not pushing these values even though console.log() prints out everything as it should on each step yet when I check the array length it's always at 0.
//This bit of code is actually inside a function and another ajax success
$.each(updatedData, function(index, element) {
$.ajax({
type: 'GET',
url: 'https://en.wikipedia.org/w/api.php?action=query&prop=extracts&exintro&explaintext&format=json&redirects&callback=?&titles='+updatedData[index],
data: { get_param: 'value' },
dataType: 'json',
success: function (data) {
console.log('success wiki');
//getting the pagenumber key value to use the extract value from it
var pagenum = Object.keys(data.query.pages);
if(data.query.pages[pagenum[0]].extract == null)
{
recycleData(index);
}
}
});
});
//this is the function which should push the trash value to the trashData
//the console.log actually logs all the correct values yet still doesn't push
function recycleData(trash){
console.log("sliced - "+trash);
trashData.push(trash);
}
//that's how the array is defined, it's obviously defined before all the functions just in case someone would ask
var trashData = [];
UPDATE: I have tested the array length after a delay, it is being populated after all the ajax requests have been completed yet I need other requests to wait for this request to finish so that the other requests will use updated data. This request is in another ajax success so keep that in mind.
If you want do other ajax on completion you can call your next ajax call on done function of previous ajax.
$.ajax({ ... }).done(second_ajax_fn);
Also you can set async:false but it is not recommended
The issue is likely that you're checking the value of trashData before the actual async requests are complete. If you want to ensure that all the requests are complete and then check it (or make more requests), you need something like jQuery Deferred - waiting for multiple AJAX requests to finish.
I'm having some problems with AJAX and the scope of my data. I am new to Javascript and I'm not sure how to fix my problem.
var urlList = new Array();
$.ajax({
url: "http://localhost:3000/url",
success: function(data) {
alert(data.expressions.url); //This shows the correct result
urlList[0] = obj.expressions.dom;
}
});
alert(urlList[0]); //this shows undefined
I need the data that is in urlList[0] so i can use it at a later time. I think it's a scope problem.
Could someone point me in the right direction please?
Thanks
It's not a scope problem, but a timing problem. The ajax method is executed asynchronously. That means that calling it will not cause your program to wait until it is finished. This results in the alert being shown before the request is finished.
To fix this, put the request inside the success function as well. This is the proper place to handle the results of the request.
var urlList = new Array();
$.ajax({
url: "http://localhost:3000/url",
success: function(data) {
alert(data.expressions.url); //This shows the correct result
urlList[0] = obj.expressions.dom;
// This might work now, depending on what `obj.expressions.dom` is. This
// isn't becoming clear from your code. Usually you would use the `data`
// parameter of the success function, which contains the response body of
// the ajax request that has just finished.
alert(urlList[0]);
// of course you can call other functions as well. For instance, you
// could call
urlListChanged();
// ..which you can declare in global scope. This way, you can repond to
// changes from multiple sources, without having to duplicate code.
// It will all work, as long as you use the success handler as the trigger.
}
});
function urlListChanged()
{
alert(urlList[0]);
}
Your problem is one of chronology.
$.ajax fires an asynchronous request, meaning the rest of your code after it will continue to be executed before the request has resolved. Since urlList is populated only once the request resolves, your alert is firing too early.
Change
$.ajax...
to
var req = $.ajax...
and wrap your alert in a success callback:
req.done(function() { alert(urlList[0]); });
...or just move the alert inside your existing success callback.
I need to load a php-script with ajax, which creates a JSON-result.
An example of the getEvent.php is:
[{"id":"1","start":"Wed Jul 18 12:00:00 GMT+0200 2012","end":"Wed Jul 18 13:30:00 GMT+0200 2012","title":"leer"}]
In order to transmit this result to another function, I have to be able to assign it to an variable. I tried it many ways, but it has never worked out.
function loadEvents(){
var cdata;
$.getJSON({
type: 'GET',
url: 'getEvent.php',
asynch:false,
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function(jsonData) {
cdata = jsonData;
},
error: function() {
alert('');
}
});
return cdata;
}
cdata = jsonData; doesnt seem to work
I have only found ways to asign parts of the result (jsonData) to a variable, but it seems that the entire jsonData can't be returned.
Can anybody help me with my problem? I have to return the complete jsonData to another function...
Thanks
getJSON is an asynchronous function (expectiong just a url, no settings object (Docu)), meaning that it will return a result as soon as the answer from the server is done. In the meantime your function continues execution. Thus, at the moment you return cdata, your success function hasn't executed yet. You need to either use a callback or set the function to be synchronous (which you are trying to do but have a typo in there - it's async without h - also if you want to pass additional settings, you can't use getJSON() but have to use $.ajax().
instead of making the call synchronous, using the callback is probably the better solution:
instead of
success: function(jsonData) {
cdata = jsonData;
},
write:
success: function(jsonData) {
workWithResult(jsonData);
},
// this is called the "callback" function, it is executed when the ajax-request
// returned successfully
function workWithResult(data){
// now you can work with the data, which is guaranteed to exist
}
First thing, why are you using getJSON?
$.ajax seems to suit more to your requirement.
Second,
The moment you return the cdata comes before the server responds. Your success handler will be executed once the server responds. In the current case, you won't be getting the data you are looking for. :)
What you can do to get around with this is to make the variable cdata global.
And just assign the value to cdata in success handler (which you have done already)
PS : Making variables global is not a good programming practice. (Or at least I don't recommend making use of global variables)
Post your specific requirement, like in what way you are going to use the returned value. So that we can see how we can avoid that global beast.
for eg:
success: function(result){
yourTargetFunction(result); // call the target function with returned data as a paramenter to it
}
I am having a problem, or perhaps a lack of understanding, with the jQuery execution order of $.get() function. I want to retrieve some information from a database server to use in the $.ready() function. As you all know, when the get returns, it passes the data to a return handler that does something with the data. In my case I want to assign some values to variables declared inside the ready handler function. But the problem is, the return handler of $.get() does not execute until after ready has exited. I was wondering if (a) am I doing this right/is there a better way or if (b) there was a way around this (that is, force the get return handler to execute immediately or some other fix I'm not aware of). I have a feeling this is some closure thing that I'm not getting about JavaScript.
As per request, I'll post an example of what I mean:
$(function() {
var userID;
$.get(uri, function(returnData) {
var parsedData = JSON.parse(returnData);
userID = parsedData.userID;
});
});
So as you can see, I'm declaring a variable in ready. Then using a get call to the database to retrieve the data needed. Then I parse the JSON that is returned and assign the userID to the variable declared before. I've tested it with a couple alerts. An alert after the get shows userID as undefined but then an alert in get's return handler shows it to be assigned.
$.get() is asynchronous. You have to use a callback to fill your variable and do the computation after the request is complete. Something like:
$(document).ready(function(){
$.get( "yourUrl", function( data, textStatus, jqXHR ) {
var myData = data; // data contains the response content
// perform your processing here...
registerHandlers( myData ); // you can only pass "data" off course...
});
});
// your function to register the handlers as you said you need to.
function registerHandlers( data ) {
// registering handlers...
}
$.get is an ajax request. A in AJAX stand for asynchronous, so script won't wait for this request to finish, but instead will proceed further with your code.
You can either use complete callback or you can use $.ajax and set async to false to perform synchronous request.
The $.get() function executes an async httprequest, so the callback function will be executed whenever this request returns something. You should handle this callback outside of $.ready()
Maybe if you explain exactly what do you want to do, it would be easier to help!
Are you looking for something like:
$(document).ready(function(){
var variable1, variable 2;
$.get('mydata.url', function(data){
variable1 = data.mydata1;
variable2 = data.mydata2;
});
});
If you declare the variables first, then you can set their values within the get call. You can add a function call at the end of the get handler to call a separate function using these values? Without some kind of example, its hard to go into any more detail.
Without seeing the full code, my guess is that you should declare your variable outside $.ready; initialize it in ready for the initial page load; then update it from the get callback handler.
for example
var x = ""; // declaration
$(document).ready(function() { x = "initial value"; });
$.get(...).success(function() { x = "updated from ajax"; });
It's probably obvious to you, but I can't figure it out.
I need to make function that returns it's inner-function's value. In other words, I have function get_users() that must return JSON object. That JSON object is got by $.post (built-in jQuery).
function get_users() {
return
$.post(
url_base + 'travel/trip/get_users/' + trip_id,
function(response) {
return response;
},
'json'
);
}
(above is what I tried to do, but it returned undefined - what a surprise)
Because of variable scope, I cannot just make variable in inner-function because it won't be visible in main function. I don't want to use global variables neither. Looking for better solution!
Thanks in any advice!
Why are you fighting against the asynchronous nature of AJAX? When you do AJAX you should get accustomed to work with events and callbacks instead of writing sequential code. You can't return the inner contents. The simple reason for this is that this inner function could execute much later than the outer function. So the outer function will return a result much before the success callback executes.
So here's the correct way:
function get_users() {
$.post(
url_base + 'travel/trip/get_users/' + trip_id,
function(response) {
// instead of trying to return anything here
// simply do something with the response
// Depending on what the server sent you there
// will be different ways.
// Here you could also call some other custom function
// and pass it the response
}
'json'
);
}
You can't return values from ajax calls. (Without setting async false, but that wouldn't really be ajax)
By the time you hit the inner return, the outer function has already completed
You will need to use a callback to process the users.
get_users(function(response) { // this anonymous function is passed in as a parameter
// do something with the response
});
function get_users(callback) {
$.post(
url_base + 'travel/trip/get_users/' + trip_id,
function(response) {
// call the passed in function and pass in the response as a parameter
callback(response);
},
json'
);
}
You need a primer on how asynchronous ajax calls work.
When you call $.post(), it starts a networking call to do the post and immediately returns from the $.post() call and continues executing the rest of your javascript. It will even exit your function get_users() right away.
But, the ajax call is not yet done - it's still in progress. Some time later, the ajax call will finish and when that happens the success handler for the ajax call that you have defined as function(response) {...} will get called. Only then, at that later time, is the response value from the ajax call known.
This is what asynchronous ajax means. You cannot write a call like get_users() and expect it to get the users and return with them. Instead, you have to make use of callback functions that will get called some time later (when the ajax has completed) and you can continue the path of your code then. Yes, this is inconvenient, but it's how things work in javascript with asynchronous ajax calls. The benefit of asynchronous ajax calls is that the browser and other javascript code can be fully live while the ajax call is underway. The cost of asynchronous ajax calls is that coding for them is more complicated.
You have a number of choices for how to deal with this complication. First off, you can make your get_users() call and then just continue the programming sequence that you want to carry out in the internal callback inside of get_users() since that's the only place that the response (the actual users) is known. If you're only using get_users() in one place in your code, then that could work fine. It would look like this:
function get_users() {
$.post(
url_base + 'travel/trip/get_users/' + trip_id,
function(response) {
// process the user list here and continue whatever other code you
// need that deals with the user list
},
'json'
);
}
If you need to use get_users() in several different places for different purposes, then you can change it to take a callback itself and let the post call just call that callback when the ajax call is done. You would then complete your processing of the response in that callback function:
function get_users(callback) {
$.post(
url_base + 'travel/trip/get_users/' + trip_id,
callback,
'json'
);
}
In this second option you could call get_users() like this:
get_users(function(response) {
// process the user list here and continue whatever other code you
// need that deals with the user list
});
There are even more advanced options available using jQuery's deferred object.