Hola, tengo una llamada a la API getItems() que devuelve datos como este:
[ { name: 'item1', materials: [ 1, 2, 3, ], }, { name: 'item2', materials: [ 2, 3, 6, ], } ... ] Y otra API llama a getMaterial(id) que devuelve los datos de un material como este:
{ name: 'mat1', img: '/img.jpg' }Lo que trato de lograr es obtener todos los datos de los artículos con los datos de los materiales. Me las arreglo para tener toda la llamada observable de materiales, pero no sé qué hacer después.
Eso es lo que he hecho hasta ahora:
public getAllItemsData(): Observable<any> { return getItems().pipe( map((list: items[]) => { return list.map(item => { const allMat = item.materials.map(m => getMaterial(m)) return forkJoin(allMat).pipe( map(data => { return { ...item, materials: data } }) ) }) }), ); }Pero no está funcionando. Gracias por la ayuda.
Prueba esto. Usando switchMap , mergeMap , from , forkJoin
getItems() .pipe( switchMap((items) => // for each items from(items).pipe( // merge map to run parallel for each items mergeMap(({ materials, ...item }) => // wait to retrive all materials details of current item at mergeMap // after completing use map to map item with retrived materials forkJoin( materials.map((m) => this.getMaterial(m)) ).pipe(map((materialDetails) => ({ ...item, materials: materialDetails }))) ) ) ) ) .subscribe((result) => { console.log(result); });Muy similar al anterior solo que con tuberías menos anidadas
interface Item { name: string; materials: number[]; } interface MaterialData { name: string; img: string; } public getAllItemsData() { return getItems().pipe( switchMap((items: Item[]) => from(items)), // use 'from' to deal with one Item at a time mergeMap(({ materials, name }: Item) => forkJoin(materials.map((mat) => getMaterial(mat))) // create array of observables using map, and pass into forkJoin .pipe( map((materials) => ({ name, materials })), // reconstruct object ), ), toArray(), // collect all emissions and output as an array ); };Creo que solo te falta una fusión/unión bifurcada final para suscribirte a la variedad de observables que has creado.
public getAllItemsData(): Observable<any> { return getItems().pipe( map((list: items[]) => list.map(item => forkJoin( item.materials.map(m => getMaterial(m)) ).pipe( map(materials => ({ ...item, materials })) ) ) ), // Subscribe to the list created above mergeMap((list:Observable<any>[]) => forkJoin(list)) ); }