Reputation: 43
I have created a service that retrieves data from a mock as follows:
export const PHOTOS: Photo[] = [
{
title: "title 1",
srcImage:"https:/34297040313_3436fd2556_k.jpg"
},
{
title: "title 2",
srcImage:"https://34297040313_3436fd2556_k.jpg"
}
}
The service is below
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Photo } from '../../model/photo';
import { PHOTOS } from './mock-photos';
import { of } from 'rxjs/observable/of';
@Injectable()
export class PhotoService {
constructor() { }
getPhotos(): Observable<Photo[]> {
return of(PHOTOS);
}
}
And in my component I use the service as follows:
getPhotos(): void {
this.photoService.getPhotos().first()
.subscribe(response => console.log(response));
}
I would expect to display only the first element and not all of the list.
Upvotes: 1
Views: 3979
Reputation: 26848
As the others have already noted the element emitted by the stream is the array.
The simplest solution is to add one more operator:
this.photoService
.getPhotos()
.flatMap(photos => photos)
.first()
.subscribe(response => console.log(response));
Or in RxJS 6:
this.photoService
.getPhotos()
.pipe(
flatMap(photos => photos),
first()
)
.subscribe(response => console.log(response));
flatMap
allows you to return an array without creating an observable first. It emits all entries of the array individually (like you had expected it in the beginning).
Upvotes: 2
Reputation: 96969
When you use of(PHOTOS)
it takes the entire array and emits it as a single item.
If you want getPhotos()
to emit each array item as a single emission you can use from(PHOTOS)
.
You can also use map
to get only the first item or you can take the first item in subscriptions:
from(PHOTOS)
.subscribe(photos => {
// photos[0]
});
from(PHOTOS)
.pipe(
first(),
)
.subscribe(photo => {
// photo
});
Upvotes: 1
Reputation: 12572
PHOTOS is an array so when you do of(PHOTOS)
it will create an observable that will emit that array as the first value. When you use the first method it will work, meaning it will return only the first item emitted by the observable, but in this case it's an array with all the values.
If you want to create an observable that will emit individual items from each item in the array you need to use the from method from(PHOTOS)
. In this case first will work as you expect.
Upvotes: 3