Reputation: 76
I'm chaining a series of Promises to operate with a database. From a first Promise, I retrieve an array of objects. In the second Promise, I generate a Promise for each object. Then, I filter the results. Here is a code example:
db.getUser(user)
.then(user=> Promise.all(
user.shirts.map(userShirt => db.getShirt(shirt.id))
) as Promise<IShirt[]>)
.then(shirts => {
shirts = shirts.filter(shirt => shirt.color === 'blue');
console.log(shirts);
})
.catch(err => {
console.log(err);
});
This is a simplified example of what my code does. The problem is in the filter operation where I retrive a 0 lenght array. Any idea?
Upvotes: 1
Views: 190
Reputation: 2452
This is how you fix the filter
operation when you retrieve a 0 length array.
One of your variable names is off:
db.getUser(user)
.then(user=> Promise.all(
user.shirts.map(userShirt => db.getShirt(shirt.id)) // <- perhaps you meant `userShirt.id` here?
))
.then(shirts => {
shirts = shirts.filter(shirt => shirt.color === 'blue')
console.log('shirts')
})
.catch(err => {
console.error(err),
})
You could be fine with that, though the bigger issue here is having to worry about Promise.all
in the first place. I wrote a library so you wouldn't have to worry about boilerplate Promise code.
Below is code equivalent to your example written with functions pipe
, map
, filter
, get
, and eq
from my library:
const db = {} // your db instance here
const getBlueShirts = pipe([
db.getUser,
get('shirts'),
map(pipe([get('id'), db.getShirt])),
filter(eq('blue', get('color'))),
])
tryCatch(getBlueShirts, console.error)(user)
further, you could map
and filter
in one fell swoop by using transform
. When you use transform
, map(...)
and filter(...)
become transducers composed with pipe
.
const getBlueShirts = pipe([
db.getUser,
get('shirts'),
transform(pipe([ // pipe([map(...), filter(...)]) is a transducer
map(pipe([get('id'), db.getShirt])),
filter(eq('blue', get('color'))),
]), [])
])
I write more about transducers here
Upvotes: 0
Reputation: 62676
Collect the promises produced by the calls to getShirt
, then run them together. Promise all will produce an array of the resolutions of those promises.
EDIT I see that you do have a Promise.all in the OP. The simple solution is to fix the undefined temp variable name:
user.shirts.map(userShirt => db.getShirt(shirt.id)) // shirt is undefined
user.shirts.map(userShirt => db.getShirt(userShirt.id))
Upvotes: 1