Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to better catch/do/empty with RXJS 5.5.2 Updates

As staten in the ionic-angular 3.9.0 release notes (https://github.com/ionic-team/ionic/blob/master/CHANGELOG.md), using the advantages of updating to RXJS 5.5.2 could reduce the bundle size and therefore lead to a faster boot time

Cool, cool, cool :)

The example provided by Ionic, to migrate for example debounceTime is pretty clear, I get it.

But it's pretty unclear to me how I should update my following code to take the full advantage of this RXJS update.

Anyone could help me to convert it or how to better write it with the goal to save bundle size?

 import {Observable} from 'rxjs/Observable';
 import 'rxjs/add/observable/empty';
 import 'rxjs/add/operator/do';
 import 'rxjs/add/operator/catch';

 intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

    return next.handle(req).do((event: HttpEvent<any>) => {
        if (event instanceof HttpResponse) {
            // do stuff with response if you want
        }
    }).catch((err: HttpErrorResponse) => {
        if ((err.status == 400) || (err.status == 401)) {
            this.interceptorRedirectService.getInterceptedSource().next(err.status);
            return Observable.empty();
        } else {
            return Observable.throw(err);
        }
    })
}

P.S.: Linked post https://forum.ionicframework.com/t/how-to-better-catch-do-empty-with-rxjs-5-5-2-updates/111559

like image 356
David Dal Busco Avatar asked Nov 09 '17 11:11

David Dal Busco


2 Answers

I came up with the following updated code which still works (tested it).

import {Observable} from 'rxjs/Observable';
import 'rxjs/add/observable/empty';
import {tap} from 'rxjs/operators/tap';
import {catchError} from 'rxjs/operators/catchError';

intercept(req: HttpRequest<any>, next: HttpHandler):   Observable<HttpEvent<any>> {

       return next.handle(req).pipe(
        tap((event: HttpEvent<any>) => {
            if (event instanceof HttpResponse) {
                // do stuff with response if you want
            }
        }),
        catchError((err: HttpErrorResponse) => {
            if ((err.status == 400) || (err.status == 401)) {
                this.interceptorRedirectService.getInterceptedSource().next(err.status);
                return Observable.empty();
            } else {
                return Observable.throw(err);
            }
        })
    );
}

Note:

  • Lettable operators have to be imported with a full import path to reduce the bundle size

    Good: import {catchError} from 'rxjs/operators/catchError'; Bad: import {catchError} from 'rxjs/operators';

  • Static doesn't change respectively they are not lettable (see https://github.com/ReactiveX/rxjs/issues/3059)

  • Static could be only imported once in app.component.ts for the all app (this won't reduce the bundle size but the code will be cleaner)

like image 184
David Dal Busco Avatar answered Oct 13 '22 01:10

David Dal Busco


Building upon the excellent answer from David Dal Buscon, I've also updated Observable.empty and Observable.throw to empty and _throw respectively

import {Observable} from 'rxjs/Observable';
import {empty} from 'rxjs/observable/empty';
import {_throw} from 'rxjs/observable/throw';
import {catchError, tap} from 'rxjs/operators';

intercept(req: HttpRequest<any>, next: HttpHandler):       
  Observable<HttpEvent<any>> {
    return next.handle(req)
      .pipe(
        tap((event: HttpEvent<any>) => {
          if (event instanceof HttpResponse) {
            // do stuff with response if you want
          }
        }),
        catchError((err: HttpErrorResponse) => {
          if ((err.status == 400) || (err.status == 401)) {                         
            this.interceptorRedirectService.getInterceptedSource()
              .next(err.status);
            return empty();
          }

          return _throw(err);
        })
     );
}
like image 30
Joe King Avatar answered Oct 13 '22 01:10

Joe King