I have an API which I can't modify. I have to use data as it is.
I want to join data from two separate requests where the second request is based on data from the first one.
I have a working solution already but the code quality, in my opinion, is low so I want to know your opinion (and if you can provide: better, more reactive solution).
So, I have an order API that's receiving data:
/orders
response:
[
{
id: 1,
clientId: 201,
// other data
},
{
id: 2,
clientId: 201,
},
{
id: 3,
clientId: 11,
}
]
In this response, I don't have data about the client name, so I have a second API where I can pass IDs of clients and then I got back:
/clientsData?ids=201,11
response:
[
{
id:201,
name: "Jon Doe"
},
{
id: 11,
name: "Jack Sparrow"
}
]
So, now I have a working code but as mentioned, in the beginning, I'm feeling it can be done in a better way. Please, note that the request should be done in the correct order because I need clients IDs before I make a second API call.
Also, want to avoid making multiple (more than two [orders+clients]) requests to check client data.
Working code:
// API Call to get orders:
const result$ = this.http.get('/orders').pipe(
mergeMap(
orders => {
const ids = orders
.map(item => item.clientId)
.filter((v, i, a) => a.indexOf(v) === i) // remove duplicates
.join(','); // get client ids into one string
// Client IDs: 1,2,99,201
// API call to check IDs:
return this.http.get(`/clientsData?ids=${ids}`).pipe(
mergeMap(clientsData => {
// map over each client
clientsData.forEach(client => {
// then map over each order
orders.forEach(order => {
// and assign client name to order
if (order.clientId === client.id) {
order.clientName = client.name;
}
});
});
return of(orders); // observable
})
);
}
)
);
result$.subscribe(console.log);
I expect to get back Observable with merged data:
[
{
id: 1,
clientId: 201,
name: "Jon Doe"
// other data
},
{
id: 2,
clientId: 201,
name: "Jon Doe"
},
{
id: 3,
clientId: 11,
name: "Jack Sparrow"
}
]
I want to avoid nested subscriptions and achieve the result in a reactive way.