Reputation: 189
I am trying to map object where correct ID will contain the array that belongs to it.
Here is the scenario:
let obj = {}
const arr = []
for (let i = 0; i < someIds.length; i++) {
const res = await someApiCall() // returns array
obj = {
id: someIds[i],
res
}
arr.push(obj)
return arr
}
The thing here is that arr
will only output last set of object because of iterating over the values.
For example I get
[{id: 122, res: "whatever122"}]
where I want to get
[{id: 122, res: "whatever122"}, {id: 111, res: "whatever111"}, {id: 133, res: "whatever133}]
How do I concatenate all?
Upvotes: 0
Views: 71
Reputation: 72256
The problem is produced by the return
statement that should probably stay outside the for
loop. It completes the execution of the current function and returns (an optional value) to the caller.
A simpler way to write what you need is to use Promise.all()
to run all the calls to someApiCall()
in parallel (if they are independent). This way the code run much faster:
async function doSomething() {
return await Promise.all(
someIds.map(
async (id) => {
return {
id: id,
res: await someApiCall(id),
};
}
)
);
}
someIds.map()
calls the callback function that it receives as argument for each item of someIds
and returns a new array that contains the values returned by the callback function.
Because the callback function is asynchronous and uses await
, it returns a Promise
as soon as the await
-ed call starts, without waiting it to complete.
The array of promises returned by someIds.map()
is passed as argument to Promise.all()
that waits for all of them and returns an array containing the values returned by the promises (which are the objects returned by the callback were they be synchronous).
The await
in front of Promise.all()
is not really needed. Without it, the function doSomething()
returns the promise returned by Promise.all()
. With it, the function returns an array of objects. Either way, the call of doSomething()
still needs to be await
-ed and the value produced by it after await
is an array of objects.
Upvotes: 0
Reputation: 153
Move the return statement outside of the for loop, which would wait for all of the objects to get added to the array.
let obj = {}
const arr = []
for (let i = 0; i < someArr.length; i++) {
const res = await someApiCall() // returns array
obj = {
id: res[i],
res
}
arr.push(obj)
}
return arr
Upvotes: 0
Reputation: 3326
You return arr
to fast. It should be returned outside the for
scope:
let obj = {}
const arr = []
for (let i = 0; i < someIds.length; i++) {
const res = await someApiCall() // returns array
obj = {
id: someIds[i],
res
}
arr.push(obj)
}
return arr
Upvotes: 2