Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rxjs: take(1) usage

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;
});
like image 654
stackdisplay Avatar asked Sep 22 '17 04:09

stackdisplay


People also ask

What is the difference between Take 1 and first () actions?

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).

What is use of take operator in RXJS?

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.

What is first () in angular?

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.

Does take automatically unsubscribe?

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!


1 Answers

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
})
like image 63
Max Koretskyi Avatar answered Sep 29 '22 23:09

Max Koretskyi