2

My script makes an Ajax request through jQuery. The data received is json_encoded via a server side script (php). This is further, stringified and then parseJSON'ed using jQuery to yield a recordCollection. I loop through recordCollection and push it onto records array, the variable that was declared outside the scope of the callback function.

The function looks like this:

var records = [] ;
$.getJSON(url, {id : recordid}, function(data) {

 var recordCollection = jQuery.parseJSON(JSON.stringify(data));

 $.each(recordCollection, function(){
  records.push(this);
 });
  console.log(records) // displays all the objects, thus, the above code is right
});  

console.log(records); // displays [] 

As you can notice above, the second time I logged records onto the console, it yielded an empty array, which is leading me to two conclusions:

  1. Javascript arrays are passed by value, hence records outside the scope of the callback function does not retain it's value.

  2. Ajax is asynchronous, hence records is being logged before the ajax call was complete and hence it still retains the value of the empty uninitialized records array and is logging that onto the console.

Now if 1 is true, how can I initialize the records array ?

And if 2 is true, should I make this Ajax call synchronous? This will make javascript block until the value is returned and thus the second time records array is logged onto the console, it will display the updated value of the array ?

The third is that I am completely missing a trick and doing something really dumb here.

I do need the records array to be set with the data returned from the ajax call as it needs to be passed around to different javascript functions in the script and the DOM basically waits for this result to load the data.

Thanks guys!

2 Answers 2

2

You are correct in that, ajax calls are async, hence Asynchronous Javascript and XML. You can make it sync, but you shouldn't because your array will then be available for anyone to play with, which can cause some big headaches.

Instead, have an init call that is run once your ajax call is completed.

function callback(records) {
  // do stuff with records.
}

$.getJSON(url, {id : recordid}, function(data) {

 var recordCollection = jQuery.parseJSON(JSON.stringify(data));
 callback(recordCollection); 
}); 
Sign up to request clarification or add additional context in comments.

3 Comments

thanks but what is app.init ? Is this a custom object method call or is it provided ?
if you will try to init records with outside variable it wont work.
I'm not sure what you mean. records is only available inside the callback function
1

Ajax stands for Asynchronous JavaScript and XML (forget the XML part) so i think you can guess what is right ;-)

I added the execution order with comments:

var records = [] ;

// 1. send request and return immediately
$.getJSON(url, {id : recordid}, function(data) {

 // 3. response from server is received
 var recordCollection = jQuery.parseJSON(JSON.stringify(data));    
 $.each(recordCollection, function(){
  records.push(this);
 });
  console.log(records)
});  

// 2. print records
console.log(records); 

You should not try to make the request synchronous in any way. If you need to do something with records after the data is available you should create a new function and call it after you pushed the values into records.

1 Comment

thanks, so maybe I could do this, if(records.length > 0) console.log(records); {assumption: data returned never has 0 records }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.