Issue
I am fairly new to Angular and RxJS, and I have a hard time wrapping my head around some aspects of RxJS operators. I have some code here (in a component):
this.salesService.getOrders().subscribe(orders => {
this.orders = orders;
this.orders.forEach((order, index) => {
this.salesService.getOrderCustomers(order.id).subscribe(customers => {
this.orders[index]['customerName'] = customers.map(c => {return c.name}).join(", ");
})
});
});
The nice thing about this is that when this.orders
is used in a table in my template, it will be available immediately, and then the column containing the customer name will populate as each call to the getOrderCustomers
service method completes.
My question is if the same can be expressed with pure RxJS, since the above does not seem to be the "RxJS way", and I would like to learn. Also, in order to isolate the fetching of customers in an effect in the NgRx ComponentStore, my understanding is that the above will not work because the effect
method must return an observable.
I have attempted something along these lines:
this.salesService.getOrders().pipe(
mergeMap(response =>
from(response.orders).pipe(
concatMap((oneOrder: object) => {
return this.salesService.getOrderCustomers(oneOrder['id'])
}),
reduce((customers, customer) => [...customers, customer], []),
map(customerList => {
/* ?? Here I would return 'response' with the customer name added into each order,
but I have no indexing of the orders to work with */
})
)
),
I have two problems - one, I do not know how to add the retrieved customer into the right place in the response.orders
variable, and secondly, the outer observable does not seem to emit until all the inner requests are done. Is there any RxJS way to progressively change the outer observable from the inner observable while initially emitting the outer observable in its original state?
I have a feeling that I am approaching this in a wrong, un-Angular and un-RxJS way. Any input would be appreciated. Thank you in advance.
Solution
Common problem, for extending array values with another value from a 2nd request.
extendedOrders$ = this.salesService.getOrders().pipe(
switchMap(orders => {
return forkJoin(orders.map(order => {
return this.salesService.getOrderCustomers(order.id).pipe(
map(customer => ({ ...order, customerName: customer.name })),
);
}));
}),
);
Answered By - MoxxiManagarm
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.