I have an AJAX request:
var foo = [],
parse = '';
$.ajax({
type: "GET",
url: "some/path/",
data: somedata
}).done(function( data ){
$.each(data.item, function(i, value){
foo.push(value);
});
parse = foo.join(', ');
});
Now the string parse is the data that I want. How can I access that data? I tried showing it using alert(), but it's not displaying anything. I think this has to do with the variable scope.
How can I get that data?
parse looks like a global variable so it will be available anywhere. The issue is probably when you're trying to access it. You can ONLY access parse in your .done() handler or some function you call from that.
The reason for this is that your ajax call is asynchronous. That means that the operation starts, the rest of your javascript continues to execute and then SOMETIME LATER the ajax call completes and ONLY then is the parse variable valid. Because of this, there really is no reason to declare the parse variable the way you have. You should just use its value inside the .done() handler.
This is asynchronous programming and works differently than synchronous, sequential programming. You must use asynchronous programming techniques with asynchronous ajax calls.
If you try to access parse inside the .done() handler and it's still empty in there, then the issue is likely that data.item isn't what you think it is and maybe isn't triggering the .each() loop and thus nothing is getting put into foo or parse. To debug this case, you should look at what exactly is in data and data.item.
This would be my suggestion:
$.ajax({
type: "GET",
url: "some/path/",
data: somedata
}).done(function( data ){
// no reason for these variables to be wider scope than here
var foo = [], parse;
$.each(data.item, function(i, value){
foo.push(value);
});
parse = foo.join(', ');
// look at parse here
console.log(parse);
// if parse still empty, then look at data and data.item here
// to see what they are for debug reasons
console.log(data);
console.log(data.item);
// now, you can use parse here
callSomeFunction(parse);
});
Related
I have a piece of JavaScript that gets data from a backend with an ajax call. There is a JSON string returned and I cannot work out why the JSON.parse is not working.
Here is my code
var success_get = (jQuery).ajax({
url: "<?php echo base_path(); ?>reservation/success_get",
method: "GET",
async: "true"
});
In Firefox I look at the console and I see the JSON returned for success_get is
{"Reservations":[{"Id":"415b68e9-1209-4ca9-9f6b-47116ced1769","ExtraDuration":0,"TotalDuration":1,"CreationTime":"2016-02-08T00:22:59+11:00","ExpiryTime":"2016-02-08T00:32:28+11:00","Sender":{"ReturnOption":"Dispose","ReturnAddress":null,"Id":"044bf5b5-95cd-44d1-a22a-8070b45a26ba","FirstName":"Test","LastName":"User","Email":"web#tz.net","Phone":"85112366"},"Recipient":{"Id":"b53ad6ac-9750-44c8-9bdd-581e89d3be93","FirstName":"Test","LastName":"User","Email":"test#test.com","Phone":"12345678"},"KioskCode":"Hm1","LockerSize":"Small","LockerNumber":"I5","Total":4.5}],"TotalAmount":4.5,"Sender":{"ReturnOption":"Dispose","ReturnAddress":null,"Id":"044bf5b5-95cd-44d1-a22a-8070b45a26ba","FirstName":"Test","LastName":"User","Email":"web#tz.net","Phone":"85112366"},"NumberOfHoursForDropOff":47}
And that looks like valid JSON as far as I can tell
I am then doing the following
success_get.done(function( success ) {
object_rsuccess = JSON.parse(success);
console.log(object_rsuccess);
});
In Firefox I get the error
ReferenceError: object_rsuccess is not defined
However in the console.log I am seeing
Object { Reservations=[1], TotalAmount=4.5, Sender={...}, more...}
And when I expand the sections in braces I am seeing the data I would expect to see.
I would have thought that I could see the variables, eg TotalAmount by doing the following
var totalamount = object_rsuccess.TotalAmount;
But this will not work while I am getting the error for object_rsuccess not defined.
Am I missing something or simply making a silly mistake?
Wrap your code which will use the object_rsuccess in a function:
var theFunctionToBeCalled = function(obj){
var totalamount = obj.TotalAmount;
console.log(totalamount);
};
Then call it within the .done():
success_get.done(function(success) {
var object_rsuccess = JSON.parse(success);
console.log(object_rsuccess);
theFunctionToBeCalled(object_rsuccess);
});
Your AJAX settings makes the function async, which means the rest of your code continues to be executed and even when you define object_rsuccess globally, it will most probably not be available for use when you need it.
Alternative to my suggestion, based on what feels comfortable to you, you can put everything using object_rsuccess within the .done() or change async:true to async:false.
Is there a way to use an event to call a function when the JSON.Parse() has parsed all the objects from a file?
JSON.parse is synchronous. it returns the object corresponding to the given JSON text.
More about it from mozilla
now a good way of doing JSON.parse is shown below (inside a try-catch)
try {
var data = JSON.parse(string);
//data is the object,
//convert to object is completed here. you can call a function here passing created object
}
catch (err) {
//mark this error ?
}
Now there are discussions, about why JSON.parse is not async, like the ONE HERE
EDIT: Since question was changed.
JSON.parse() is a synchronous method, meaning that once it's called it will execute fully, before code execution continues.
var obj= JSON.parse(jsonString);
obj.prop; // obj is already accessible.
JSON.parse, doesn't actually load any files. It's also synchronous, meaning that code execution resume, after it has finished it's function, which is to parse a valid JSON string, to a JavaScript object.
If you want to execute a callback after a file has loaded, you'd need to look into requests, and ajax to be more precise. Here's a simple example using jQuery.
$.ajax({
url: 'url/to/file.json',
dataType: 'json'
}).done(yourCallback);
I try to manipulate a variable inside a function. But it seems to forget the values once I exit the function, eventhough the variable is declared outside the function.
The essential code:
var posts = {};
// Perform a data request
// skjutsgruppens-page
$.oajax({
url: "https://graph.facebook.com/197214710347172/feed?limit=500",
*SNIP*
success: function(data) {
$.extend(posts, data);
}
});
// Gruppen
$.oajax({
url: "https://graph.facebook.com/2388163605/feed?limit=500",
*snip*
success: function(data) {
$.extend(posts, data);
}
});
The oajax retrievies data from facebook. I want to make a variable that contains the data from both oajax methods.
The actual code: http://eco.nolgren.se/demo/resihop/#
The issue is likely that the success function executes at an arbitrary time in the future--unless you specifically access posts after you know the success function has executed, you will receive undefined results, completely dependent on function and access timing.
The best approach is to handle this correctly by doing necessary work inside in the success function, or use something like jQuery's .when function.
I have a situation where I need to initialize/assign variables from the results of a jQuery AJAX call, and then re-use those variables further on down the script:
var shouldRedirect = ???
$.ajax({
url: 'http://example.com',
type: 'GET',
data: 'blah',
asynch: false,
timeout: 1800,
success: function(data) {
shouldRedirect = data.rows[0].redirectFlag
}
});
if(shouldRedirect)
window.location = "...";
Two issues I'm having:
Assuming the resultant JSON will contain a redirectFlag boolean, is data.rows[0].redirectFlag the proper way of obtaining the value for my variable?; and
What do I initialize shouldRedirect to before the AJAX is kicked off (how do I say "create a variable but don't give it a value yet!")?
Thanks in advance!
You can declare uninitialized variables by simply doing the following:
var shouldRedirect;
If your logic requires it you can of course initialize it to false:
var shouldRedirect = false;
This might not be what you desire though. You can check if a variable was initialized by strictly comparing it to undefined:
if (shouldRedirect === undefined) // do something
Note though, that you must use the triple equal operator (aka strict equality) or your results will not be as expected. On the other side, an undefined variable will yield a falsy result. This means that when checking a variable with a simple if (shouldRedirect) and the variable is undefined then it will yield false, as if it was set to false. This is also true for a couple of other values in JavaScript, eg the empty string "" or the value null. You can see a complete list of falsy values here. If you want to check explicitly for true or false and want to omit other falsy or truthy values, then you should check with triple equality, eg if (shouldRedirect === true).
Also, if data.rows[0].redirectFlag is the correct way to access the value is highly dependend on how the data structure you receive from your AJAX call actually looks like. If it is something like the following it would be correct:
{ rows: [ {redirectFlag: true}, {redirectFlag: false} ] }
If your JSON looks like the following though
{ redirectFlag: false }
then you have to access redirectFlag simply with data.redirectFlag.
What do I initialize shouldRedirect to before the AJAX is kicked off (how do I say "create a variable but don't give it a value yet!")?
You could just do: var shouldRedirect;
However, I would do var shouldRedirect = false; to ensure shouldRedirect is not undefined
Is data.rows[0].redirectFlag the proper way of obtaining the value for my variable?
Depends what you send back from the AJAX request. Usually responses are in JSON so if you send a JSON object back with a value true then you could do:
shouldRedirect = data.redirectFlag;
For part #1 to declare a variable with it having a value use:
var shouldRedirect. This way you can just do a if (!shouldRedirect) {}.
For part #2. How to get the value from redirectFlag is based on the formation of the data returned from the ajax call. data... would be the starting point for you to get the value.
As mentioned in the comments section, setting the shouldRedirect flag isn't going to help as the if statement that follows the $.ajax request will be evaluated before the result is fetched from the server - this is a common problem faced in asynchronous code execution. Although you can, in theory, force jQuery.ajax into syncronous mode via the sync parameter, I wouldn't recommend doing so as it will lock up the browser UI whilst the request is made.
You need to move your redirection code into the $.ajax success function like so:
$.ajax({
url: 'http://example.com',
// ... other options omitted for brevity
success: function(data) {
// This code block gets executed when the operation completes.
var shouldRedirect = data.rows[0].redirectFlag
if (shouldRedirect) {
// Your redirection code goes here.
window.location = "...";
}
}
});
If you using of jQuery 1.7 or greater, you can make use their Promises/A implementation via the defered object. Defered object's allow you to execute one or more functions when an operation completes and makes the async code easier to read.
$.ajax({ url: 'http://example.com' })
.done(function(data) {
// This code block gets executed when the operation completes.
});
Instead of passing a function closure to done, you can also pass a reference to a member function, eg:
$.ajax({ url: url }).done(onDataLoaded);
function onDataLoaded(data) {
// This function gets called when the ajax operation completes.
}
I hope this is not too much of a newbe question but I've been pulling my hair out for a while now so thought I'd give in and ask for my first piece of advice on here.
I'm trying to read an external xml file using javascript / jQuery / ajax and place the retrieved data into an array so that I can then reference it later.
So far I seem to be doing everything right upto the point I put the data into the array but then I'm struggling to to read the data anywhere other than inside the function where I create it. Why am I not able to access the Array from anywhere other than in that function?
Here is my code...
Please help!!
$.ajax({
type: "GET",
url: "data.xml",
dataType: "xml",
success: do_xmlParser
});
function do_xmlParser(xml)
{
var myArray = new Array();
$(xml).find("tag").each(function ()
{
myArray.push($(this).find("innerTag").text());
});
console.log("inside "+myArray); // This outputs the array I am expecting
return myArray; // is this right???
}
console.log("outside: "+myArray); // This does NOT output the array but instead I get "myArray is not defined"
You're defining do_xmlParser as a callback to an asynchronous function (success of the jquery ajax call). Anything you want to happen after the ajax call succeeds has to occur within that callback function, or you have to chain functions from the success callback.
The way you have it now, the actual execution of code will go:
ajax -> file being requested -> console.log ->
file transfer done -> success handler
If you're doing some critical stuff and you want the call be to synchronous, you can supply the
async : false
setting to the ajax call. Then, you should be able to do something like this:
var myArray = [],
do_xmlParser = function (xml)
{
$(xml).find("tag").each(function ()
{
myArray.push($(this).find("innerTag").text());
});
};
$.ajax({
type: "GET",
url: "data.xml",
dataType: "xml",
success: do_xmlParser,
async: false
});
console.log("outside: " + myArray);
The async option doesn't work for cross-domain requests, though.
NOTE
I don't recommend doing this. AJAX calls are supposed to be asynchronous, and I always use the success callback to perform all of the processing on the returned data.
Edit:
Also, if you're into reading... I'd recommend jQuery Pocket Reference and JavaScript: The Definitive Guide (both by David Flanagan).
look close and you will see. You are actually firing up an array that dosen't exist. You have declared myArray inside function. Try do something like this.
console.lod("outside :"+do_xmlParser(xml)); // I think that when you merge a string and an array it will output only string, but I can be wrong.