Reputation: 925
I load some data for multiple users and I want to store it into a javascript array. In pure typescript, I will write it like that:
for(var i = 0; i < 5; i++) {
promise[i] = httpquery.then(
(data) => { this.usersData[i] = data }
);
)
...
this.$q.all[promise].then(......
unfortunately, my typescript lambda protect only this (and not the variable i). So in my case it will always store the data in this.usersData[5].
Right, I need a closure, and what lambda expression do is a bit similar to a closure as far as I understand this typescript's part of language.
so let try to do something with Typescript :
for(var i = 0; i < 5; i++) {
promise[i] = (index = i) => {
return httpquery.then(
(data) => { this.usersData[index] = data }
);
}();
)
which not work at all (not even compile). Why ? because seems that () => {} is not really a function. I solved this by using this way :
for(var i = 0; i < 5; i++) {
var getData = (index = i) => {
return httpquery.then(
(data) => { this.usersData[index] = data }
);
};
promise[i] = getData();
)
which I found not super beautiful :-p. So my question is: how to proceed in this case of issue ? Like I did ? Or there is a way to use the lambda in typescript in a more beautiful way ? And why
() => {}()
isn't working but
var test = () => {};
test();
works ? It it because of the typescript compiler which is not "smart" enough to understand that the lambda is a function ?
Thanks.
Upvotes: 4
Views: 2355
Reputation: 159905
The reason why:
promise[i] = (index = i) => {
return httpquery.then(
(data) => { this.usersData[index] = data }
);
}();
doesn't parse is because it isn't valid JavaScript (var x = a => { return a + 1; }(3)
is a SyntaxError
in JavaScript as well as TypeScript. Simply wrapping the lambda in parenthesis is enough to make it a valid expression.
However, simply doing that will not fix your capturing issue - default arguments are evaluated on each call, and so they will all point at the final bound value of the var
.
Instead you can either:
A) Switch to using let
in your initializer (in which case TypeScript will automatically do the right thing:
for(let i = 0; i < 5; i++) {
promise[i] = httpquery.then(data => this.usersData[i] = data);
}
B) Manually create the closure yourself:
for(var i = 0; i < 5; i++) {
promise[i] = (index => httpquery.then(data => this.usersData[index] = data))(i);
}
Upvotes: 3