Reputation: 6769
I'm using AngularJS and Angular Translate. I have an array of objects that have 'key' property - a string that should be translated.
This is my array of objects:
var objects = [{
id: 1,
key: 'Jacket'
}, {
id: 2,
key: 'Trousers'
}, {
id: 3,
key: 'Hat'
}];
These are my translations:
var translationsEN = {
Jacket: 'This is Jacket in English',
Trousers: 'This is Trousers in English',
Hat: 'This is Hat in English'
}
When some particular events occur I need an array of the objects but with the translations, not with the keys. That's why I have a function that does the following:
var translatedObjects = [];
for (var i = 0; i < objects.length; i++) {
$translate(objects[i].key).then(function (translation) {
translatedObjects[i] = translation;
});
}
After the function execution the result stored in the translatedObjects array is:
[null,null,null,"This is Hat in English"]
I guess that this is happening because I'm actually executing an asynchronous call to the $translate service and translatedObject[i] is not actually pointing to the right object, because 'i' is not defined in the current context.
So, how can I execute an asynchronous function call and assign my array appropriately as shown in the example above?
Upvotes: 0
Views: 89
Reputation: 13682
You're already using promises so you can use Promise.all()
:
var promises = [];
for (var i = 0; i < objects.length; i++) {
promises.push($translate(objects[i].key));
}
Promise.all(promises).then(function (translatedObjects) {
// use your array here
});
Upvotes: 0
Reputation: 129802
Yes, the for loop will have completed and the value of i
will be 3
when the callback fires. The three callbacks will then overwrite the value at the same index three times.
You can encapsulate your variable in a new scope:
for (var i = 0; i < objects.length; i++) {
$translate(objects[i].key).then((function(x) {
return function (translation) {
translatedObjects[x] = translation;
};
})(i));
}
What happens above is you create an anonymous function that accepts a parameter, x
, and returns a callback function. So when you call that function passing i=0
, it will return a callback function which has access to x=0
from the scope in which it was created. At the next iteration, the anonymous function will be called again, and return a new callback function, where x
is 1, etc.
If you know that the callbacks will be called sychronously, and assigning to an array is all you want to do, then ngLover's answer is probably more readable.
Upvotes: 1
Reputation: 4578
You can use push
method of array to insert data . don't need to pass i
since it will be inserted in same sequence.
for (var i = 0; i < objects.length; i++) {
$translate(objects[i].key).then(function (translation) {
$scope.translatedObjects.push(translation);
});
}
Upvotes: 1