OK, so I’m going to pretend it doesn’t exist and instead listen to you when you say:
In my world, pages are queens. We do not ask queens to shop for their own groceries and cook their own meals (unless they enjoy doing these things, of course).
In more practical terms, I write providers so that they deliver exactly the data that pages want. In this case, that seems to be “a list of favorite items”.
You could do this either in FavoriteProvider
or ProducoesProvider
, whichever feels more natural to you. I’m going to do it in ProducoesProvider
.
export class ProducoesProvider {
constructor(..., _favs: FavoriteProvider) {}
allProducts(): Observable<Producao[]> {
// do whatever existing `getProdsList()` does
}
favoriteProducts(): Observable<Producao[]> {
// this is fairly deep magic, so will comment extensively
return this.allProducts().pipe(
// convert flat array of all products to an Observable
// that emits one at a time, change over to watching that
switchMap(ap => from(ap)),
// now turn each product into a stream that will emit
// itself only if it is a favorite
mergeMap(p => {
// since the favorite check is a Promise, convert that
// to an Observable, and kick off another stream
return from(this._favs.isFavorite(p)).pipe(
// the filter operator will abort the stream if whatever
// isFavorite eventually returned isn't truthy
filter(Boolean),
// ok, we're a favorite, but all we have at this point is
// 'true', which isn't much help, because we want the
// product instead. enter the mapTo operator
mapTo(p)
);
}),
// we're almost there. now we have a stream of favorite
// products. if you're using AsyncPipe in your template,
// this might be sufficient, but we've declared that we're
// going to return a complete array, so let's flatten our
// stream into one
toArray()
);
}
}