I'm trying to use map to return a new field at an array of objects and once i do it returns empty.
Expected result:
[
{
"id": 2,
"name": "awesome stadium",
"opened": "1970-01-01T00:00:00.000Z",
"capacity": "39590.00",
"location": "some awesome",
"team_id": "147ff48e",
"team": {
"name": "some name",
"location": "some location"
}
}
]
Code:
const venues = await connection(VENUE_TABLE)
.limit(LIMIT_PER_PAGE)
.offset((page - 1) * LIMIT_PER_PAGE)
.select('*');
const venuesWithTeam = venues.map(async (element) => ({
...element,
team: await connection('team')
.where('id', element.team_id)
.select('*')
.first(),
}));
return response.json(venuesWithTeam);
What could i do to make it work as expected?
I'm trying to use map to return a new field at an array of objects and once i do it returns empty.
Expected result:
[
{
"id": 2,
"name": "awesome stadium",
"opened": "1970-01-01T00:00:00.000Z",
"capacity": "39590.00",
"location": "some awesome",
"team_id": "147ff48e",
"team": {
"name": "some name",
"location": "some location"
}
}
]
Code:
const venues = await connection(VENUE_TABLE)
.limit(LIMIT_PER_PAGE)
.offset((page - 1) * LIMIT_PER_PAGE)
.select('*');
const venuesWithTeam = venues.map(async (element) => ({
...element,
team: await connection('team')
.where('id', element.team_id)
.select('*')
.first(),
}));
return response.json(venuesWithTeam);
What could i do to make it work as expected?
Share Improve this question asked Apr 20, 2020 at 4:33 silva_edilson22silva_edilson22 452 silver badges8 bronze badges 2-
venuesWithTeam
will be an array of Promises - it's not empty - it's only empty because you're trying to convert a Promise to JSON - which results in nothing – Jaromanda X Commented Apr 20, 2020 at 4:36 -
try
const venuesWithTeam = await Promise.all(venues.map .... etc)
– Jaromanda X Commented Apr 20, 2020 at 4:38
3 Answers
Reset to default 5async
functions always return a Promise, but .map
does not "await" these promises (it just put them "as is" in the result). If you want to get all the results, the simplest way would be Promise.all
:
const venuesWithTeam = await Promise.all(venues.map(async (element) => ({
...element,
team: await connection('team')
.where('id', element.team_id)
.select('*')
.first(),
})));
Note: this will start running all the operations in parallel (simultaneously) and wait for all of them to be resolved before continuing. If venues
is a very large array, it could cause a large number of connections to your database and potentially cause some issues.
To run the requests one after the other, you will have to loop and wait for the previous one to be resolved. One way to do that can be done using reduce
.
const venuesWithTeam = await venues.reduce((prom, element) => (
prom.then(async result => (
result.concat({
...element,
team: await connection('team')
.where('id', element.team_id)
.select('*')
.first(),
})
))
), Promise.resolve([]));
venues.map will return an array of Promises. Promises don't stringify to JSON - well, they do, to {}
So, you must await all the promises returned by .map in your code
so, Promise.all(x.map( ..... ))
i.e.
const venuesWithTeam = await Promise.all(venues.map(async(element) => ({
...element,
team: await connection('team')
.where('id', element.team_id)
.select('*')
.first(),
})));
return response.json(venuesWithTeam);
Or, to run each iteration in series rather than parallel
const venuesWithTeam = [];
for (element of venues) {
venuesWithTeam.push({
...element,
team: await connection('team')
.where('id', element.team_id)
.select('*')
.first(),
});
}
return response.json(venuesWithTeam);
You need to use Promise.All
in your code.
const venuesWithTeam = await Promise.all(venues.map(async (element) => ({
...element,
team: await connection('team')
.where('id', element.team_id)
.select('*')
.first(),
})));
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744870155a4598211.html
评论列表(0条)