Reputation: 19655
I'm fairly new to Observables, RxJS and Angular in general. I'm using Angular 7 (Ionic 4) and am having a hard time wrapping my head around a solution to the problem below.
In my application, I make an HTTP GET request as follows:
myData = this.http.get("https://example.com/api").pipe(
map(results => {
return results["payload"]
})
)
This HTTP GET request returns an Observable myData
which has the following data:
const data = [
{
"id": 1,
"name": "abc",
"description": "test1"
},
{
"id": 2,
"name": "def",
"description": "test2"
},
...
...
]
I want to add another key color
to each object in this array like this:
const data = [
{
"id": 1,
"name": "abc",
"description": "test1",
"color": "green"
},
{
"id": 2,
"name": "def",
"description": "test2",
"color": "red"
},
...
...
]
Instead of hard coding the value of color
for each object, I want to retrieve this key value from a function getColor(id)
which is in another service called colorService
.
The problem is that that colorService.getColor(id)
returns an Observable.
The question: How can I subscribe to colorService.getColor(id)
for each object in my array?
I want to do something like this:
const data = [
{
"id": 1,
"name": "abc",
"description": "test1",
"color": <subscribe to colorService.getColor(1)>
},
{
"id": 2,
"name": "def",
"description": "test2",
"color": <subscribe to colorService.getColor(2)>
},
...
...
}
I hope I'm clear. My concepts are rather weak at this point, so apologizes if some of it sounds confusing.
Upvotes: 1
Views: 258
Reputation: 5612
This is what you can do [See the explanation in the code comments]-
myData = this.http.get("https://example.com/api")
.pipe(
mergeMap(results => {
const data = results["payload"];
//I am assuming that `data` is the array that you mentioned in your question
//Iterate through each of the object in the array and map it to an observable which
//will fetch the color and then return the data with color
//obs will be an array of observables for each data
const obs = data.map(d => {
return this.colorService.getColor(d.id)
.pipe(
map(color => {
return {...d, color};
})
);
});
//wait for all the obs to be returned;
return forkJoin(obs);
}),
tap(dataArrayWithColor => {
//dataArrayWithColor will have an array of object which will have data with color
console.log(dataArrayWithColor);
})
);
Hope it helps.
Upvotes: 2