I am starting my project with Angular2 and the developers seem to recommend RXJS Observable instead of Promises.
I have achieved to retrieve a list of elements (epic
You'll want to filter the actual array and not the observable wrapped around it.
So you'll map the content of the Observable (which is an Epic[]
) to a filtered Epic
.
getEpic(id: string): Observable<Epic> {
return this.getEpics()
.map(epics => epics.filter(epic => epic.id === id)[0]);
}
Then afterwards you can subscribe
to getEpic
and do whatever you want with it.
You can do this using the flatMap
and filter
methods of Observable
instead of the JS array filter method in map
. Something like:
this.getEpics()
.flatMap((data) => data.epics) // [{id: 1}, {id: 4}, {id: 3}, ..., {id: N}]
.filter((epic) => epic.id === id) // checks {id: 1}, then {id: 2}, etc
.subscribe((result) => ...); // do something epic!!!
flatMap
will provide singular indices for filtering and then you can get on with whatever happens next with the results.
If TypeScript throws a error indicating you can't compare a string and a number regardless of your use of ==
in the filter just add a +
before epic.id
in the filter, per the Angular docs:
.flatMap(...)
.filter((epic) => +epic.id === id) // checks {id: 1}, then {id: 2}, etc
.subscribe(...)
Example:
https://stackblitz.com/edit/angular-9ehje5?file=src%2Fapp%2Fapp.component.ts
You have to subscribe on Observable
s to get the data, since http calls are async in JavaScript.
getEpic(id: number, callback: (epic: Epic) => void) {
this.getEpics().subscribe(
epics: Array<Epic> => {
let epic: Epic = epics.filter(epic => epic.id === id)[0];
callback(epic);
}
);
}
You can call that method then like this:
this.someService.getEpic(epicId, (epic: Epic) => {
// do something with it
});
original answer with a fix:
Observables
are lazy. You have to call subscribe
to tell an observable
to send its request.
getEpic(id:number) {
return this.getEpics()
.filter(epic => epic.id === id)
.subscribe(x=>...);
}
Update to Rxjs 6:
import {filter} from 'rxjs/operators';
getEpic(id:number) {
return this.getEpics()
.pipe(filter(epic => epic.id === id))
.subscribe(x=>...);
}