Reputation: 91213
I have the following type of structure:
(function(){
var objects = [];
$('button.one').on('click', function(){
fetchObjects = function(objects) {
$.post("/fetchObjects")
.done(function(data){
objects = data;
console.log(objects.length);
});
}
fetchObjects(objects)
});
$('button.two').on('click', function(){
console.log(objects.length);
});
})();
You can see I have a variable objects
that is local to this function. Initially its empty. When I click button.one
I wish to populate objects
with the returned value from some ajax request. It appears to work, however when clicking button.two
, the objects
variable is still an empty array.
Why isn't objects
available in the jQuery callback?
I've also tried this approach but with the same results:
function callback(data) {
facilities = data
}
$.post("/fetchObjects")
.done(function(data){
callback(data);
});
What am I missing here? Please don't tell me to make "objects" global.
Upvotes: 0
Views: 46
Reputation: 33153
Let's simplify the code a bit. You have essentially this:
var objects = [];
fetchObjects = function(innerObjects) {
var data = ['a','b'];
innerObjects = data;
console.log(innerObjects.length);
};
fetchObjects(objects);
console.log(objects);
(I've changed the other objects
variable's name just for clarity; the issue is the same even if it had the same name.)
When you call the function, innerObjects
contains a reference to objects
so modifying it would change the original array as well. But when you do
innerObjects = data;
now instead of modifying the array you're replacing the reference with something else. innerObjects
"points" to data
instead of objects
and the original variable remains unchanged.
To make it work you'd need to loop through the data
array (assuming it'll always be an array) and assign the contents to the objects
reference one by one. This way you'll keep the original reference and modify the original array.
var objects = [];
fetchObjects = function(innerObjects) {
var data = ['a','b'];
for( var i = 0; i < data.length; i++ ) {
innerObjects[i] = data[i];
}
console.log(innerObjects.length);
};
fetchObjects(objects);
console.log(objects);
Or, in your actual code:
(function(){
var objects = [];
$('button.one').on('click', function(){
fetchObjects = function(objects) {
$.post("/fetchObjects")
.done(function(data){
for( var i = 0; i < data.length; i++ ) {
objects[i] = data[i];
}
console.log(objects.length);
});
}
fetchObjects(objects)
});
$('button.two').on('click', function(){
console.log(objects.length);
});
})();
Upvotes: 0
Reputation: 555
I don't know why you're passing objects as parameter. The following should work fine I think. Please let me know if you're trying to achieve something else.
(function(){
var objects = [];
$('button.one').on('click', function(){
fetchObjects = function() {
$.post("/fetchObjects")
.done(function(data){
objects = data;
console.log(objects.length);
});
}
fetchObjects()
});
$('button.two').on('click', function(){
console.log(objects.length);
});
})();
Upvotes: 1