Reputation: 1743
I've been learning Angular recently and am trying to better understand RxJS. Assume I have an API response from HttpClient.get that gives me an Observable of the following JS object:
const response = {
photos: [
{
id: 1,
src: '1.jpg',
},
{
id: 2,
src: '2.jpg',
},
{
id: 3,
src: '3.jpg',
}
]
}
The end result I'm looking for is: ['1.jpg', '2.jpg', '3.jpg']
I am able to do the following to get each individual src one at a time:
const source = from(response.photos);
const images = source.pipe(
pluck('src')
);
images.subscribe({
next(x) {
console.log(x); // results in: 1.jpg 2.jpg 3.jpg, one item per line.
}
});
But what I'd like to do, and what I thought would work, is to create an observable of the entire response (as it would be given from Angular's http.get() call) and return all src properties as an array, like this:
const source = of(response);
const images = source.pipe(
pluck('photos'), // i expect this to be [{ id: 1, src: '1.jpg' }, ... ]
map(x => x.src), // i expect x to to be { id: 1, src: '1.jpg' } (but it is not)
);
images.subscribe({
next(x) {
console.log(x); // i expect x to be the result of the map call earlier, i.e. ['1.jpg', '2.jpg', '3.jpg']
}
});
I suppose I'm likely getting hung up on expecting the final value vs. the values as they arrive, or something to that effect. If anyone can help explain how to get the desired result or suggest a different/better approach, I'm hoping that something will click and things will start to make more sense.
Upvotes: 0
Views: 3091
Reputation: 874
Here i have substituted your client call with getImages()
method
In addition to this always follow up the unscubscribing the observables in the ngDestroy method to prevent from memory leaking
let images;
let imageSrc;
getImages(): Observable<any> {
return this.httpClient.get(url);
}
this.getImages().pipe().subscribe(response =>
{
this.images = response.photos;
this.imageSrc = response.map(x => x.src)
});
Upvotes: 0
Reputation: 1381
As you need just some data manipulation after get the source's result without any event manipulation, I like to simply use a map like this:
const source = of(response);
const images = source.pipe(map(data => data.photos.map(x => x.src)));
images.subscribe(console.log);
Upvotes: 2
Reputation: 1177
Considering your second approach, there you have an error in the map
operator.
Basically you are passing an array to the observable and in the map
operator the result is expected to be an array and not an object like you are treating it there.
The correct code is the following:
const source = of(response);
const images = source.pipe(
pluck("photos"),
// here map over the output which is an array
map(x => x.map(y => y.src))
);
images.subscribe({
next(x) {
console.log(x); // the result is: ['1.jpg', '2.jpg', '3.jpg']
}
});
Upvotes: 0