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 difference is that take(1) will relay 0..1 items from upstream whereas first will relay the very first element or emits an error (NoSuchElementException) if the upstream is empty. Neither of them is blocking. It is true first == take(1).
take returns an Observable that emits only the first count values emitted by the source Observable. If the source emits fewer than count values then all of its values are emitted. After that, it completes, regardless if the source completes.
The first() operator takes an optional predicate function and emits an error notification when no value matched when the source completed. For example this will emit an error: import { EMPTY, range } from 'rxjs'; import { first, take } from 'rxjs/operators'; EMPTY.
take. The take operator allows us to specify how many values we want to receive from the Observable before we unsubscribe. This means that when we receive the specified number of values, take will automatically unsubscribe! Once obs$ has emitted five values, take will unsubscribe automatically!
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. You can read more about take operator here. Its 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
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With