Reputation: 21104
I have this piece of RxJS code
this.listItems$ = this.store.select(EntityState.relationshipItems).pipe(
map(fn => fn(12)),
mergeMap(items => items),
map(this.toListItem),
toArray<ListItem>(),
tap(x => console.log(x))
);
Using mergeMap(items => items)
I'm trying to "flatten" the array, then map
each item to another object, and then convert it back to an array.
However, the flow doesn't even reach the last tap
. I can see the toListItem
function is called, but I don't understand why it stops there.
Transforming it to
this.listItems$ = this.store.select(EntityState.relationshipItems).pipe(
map(fn => fn(12)),
map(items => items.map(this.toListItem)),
tap(x => console.log(x))
);
makes it work, but I'd like to understand why the above one doesn't work.
Upvotes: 1
Views: 118
Reputation: 96891
That's because this.store.select(...)
is a Subject that never completes (if it did then you could select data just once which doesn't make sense).
However, toArray
collects all emissions from its source and when its source completes it emits a single array. But the source is this.store.select(...)
that never completes so toArray
never emits anything.
So probably the easiest workaround would be just restructuring your chain:
this.listItems$ = this.store.select(EntityState.relationshipItems).pipe(
map(fn => fn(12)),
mergeMap(items => from(items).pipe(
map(this.toListItem),
toArray<ListItem>(),
tap(x => console.log(x))
)),
);
Now the source is from
that completes after iterating items
so toArray
will receive complete notification and emit its content as well.
Upvotes: 1