[SOLVED] 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 :slight_smile:

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

Anyone could help me to convert it?

 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);
        }
    })
}

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 (see good idea of @AaronSterling for a cleaner code down here)

Are empty and throw not lettable?
Edit: I see, creation ops don’t need to be lettable. But does that mean you import empty one time in app.component.ts?

According following post/issue, no they are not lettable https://github.com/ReactiveX/rxjs/issues/3059

I only use empty there so it will be imported one time.

On the other hand, I used forkJoin a freaking lot of times and I have to add the import (like following) in every classes…but since Rxjs is packaged in vendor.js, at least, I guess, I don’t end-up with multiple duplication of the codes.

import 'rxjs/add/observable/forkJoin';

It’s just no luck that doing so it seems that other operators are also loaded in the bundle respectively I wasn’t able to spare bundle size…but at least, my bundle is not bigger now as before :wink:

But if you see something wrong, don’t hesitate to teach me how to improve it, I would love to reduce my bundle size and improve my code!

This is brand new to me too, so I doubt I’ll be teaching anyone anything, except hopefully to myself. But here’s something I don’t understand. Is it better to import forkJoin once in app.component.ts, or 10 times in 10 different pages/providers? In general, I care more about startup speed than I do about smaller size. If it takes extra splash screen time to deal with imports in app.component.ts, then I’d rather import forkJoin 10 times, later on. But maybe it isn’t faster? Do you know?

Actually I never tried…give me five, I just quickly finish a feature and switch to that…thx for the idea, super interesting!

@AaronSterling same same

Importing these static only in app.component or everywhere where you use it kind of doesn’t change the build size, it’s like +/- 1kb

According source-map-explorer, my Rxjs was even a bit bigger, 0.2 Kb if I only import them in app.component.ts

But the code is more clean :wink:

1 Like