I have seen a tutorial on rxjs as like this.
My question is:
1) What is the usage of take(1)
here? I see a lot of explanation online but i don't really get it. Also, i don't see any benefit of using take(1)
in this code. And the author do use take(1)
on every return function in REST api related service.
2) The author did not unsubscribe after subscribe. Is it because the author use take(1)
therefore manual unsubscribe is not needed?
3) What if i want to implement catch function. Should i implement it before take or after take.
getProfile() { // this is a call to REST API
return this.service.getProfile()
.map(res => res.json())
.take(1)
}
}
this.data.getProfile().subscribe(profile => {
this.userProfile = profile;
});
The author did not unsubscribe after subscribe. Is it because the
author use take(1) therefore manual unsubscribe is not needed?
Yes, that is most likely why the author uses take(1)
operator. It's job is to pass one value to an observable and then unsubscribe from the source. But depending on the service it may not be required.
For example in Angular the HttpClient
service completes the stream by itself after sending the final HttpResponse
event value so you don't need to neither use take
nor unsubscribe explicitly. Here is the sources:
@Injectable()
export class HttpXhrBackend implements HttpBackend {
...
handle(req: HttpRequest<any>): Observable<HttpEvent<any>> {
...
// Everything happens on Observable subscription.
return new Observable((observer: Observer<HttpEvent<any>>) => {
...
// First up is the load event, which represents a response being fully available.
const onLoad = () => {
...
if (ok) {
// A successful response is delivered on the event stream.
observer.next(new HttpResponse({
body,
headers,
status,
statusText,
url: url || undefined,
}));
// The full body has been received and delivered, no further events
// are possible. This request is complete.
observer.complete(); <---------------------------------
}
What if i want to implement catch function. Should i implement it before take or after take.
You can implement it after take
since take
will also transmit the error.
const stream = Observable.create((observer) => {
observer.error(new Error());
}).take(1).catch(() => {
return Observable.of(`An error occurred`);
}).subscribe((v) => {
console.log(v); // An error occurred
})