Search code examples
angulartypescriptrxjsangular2-observables

Best way to import Observable from rxjs


In my angular 2 app I have a service that uses the Observable class from the rxjs library.

import { Observable } from 'rxjs';

At the moment I am just using Observable so that I can use the toPromise() function.

I read in another StackOverflow question somewhere that importing in this way and also importing from rxjs/Rx will import a whole lot of unnecessary stuff from the rxjs library that will increase the page load times and/or the code base.

My question is, what is the best way to import Observable so I can use the toPromise() function without having to import everything else?


Solution

  • Rxjs v 6.*

    It got simplified with newer version of rxjs .

    1) Operators

    import {map} from 'rxjs/operators';
    

    2) Others

    import {Observable,of, from } from 'rxjs';
    

    Instead of chaining we need to pipe . For example

    Old syntax :

    source.map().switchMap().subscribe()
    

    New Syntax:

    source.pipe(map(), switchMap()).subscribe()
    

    Note: Some operators have a name change due to name collisions with JavaScript reserved words! These include:

    do -> tap,

    catch -> catchError

    switch -> switchAll

    finally -> finalize


    Rxjs v 5.*

    I am writing this answer partly to help myself as I keep checking docs everytime I need to import an operator . Let me know if something can be done better way.

    1) import { Rx } from 'rxjs/Rx';

    This imports the entire library. Then you don't need to worry about loading each operator . But you need to append Rx. I hope tree-shaking will optimize and pick only needed funcionts( need to verify ) As mentioned in comments , tree-shaking can not help. So this is not optimized way.

    public cache = new Rx.BehaviorSubject('');
    

    Or you can import individual operators .

    This will Optimize your app to use only those files :

    2) import { _______ } from 'rxjs/_________';

    This syntax usually used for main Object like Rx itself or Observable etc.,

    Keywords which can be imported with this syntax

     Observable, Observer, BehaviorSubject, Subject, ReplaySubject
    

    3) import 'rxjs/add/observable/__________';

    Update for Angular 5

    With Angular 5, which uses rxjs 5.5.2+

    import { empty } from 'rxjs/observable/empty';
    import { concat} from 'rxjs/observable/concat';
    

    These are usually accompanied with Observable directly. For example

    Observable.from()
    Observable.of()
    

    Other such keywords which can be imported using this syntax:

    concat, defer, empty, forkJoin, from, fromPromise, if, interval, merge, of, 
    range, throw, timer, using, zip
    

    4) import 'rxjs/add/operator/_________';

    Update for Angular 5

    With Angular 5, which uses rxjs 5.5.2+

    import { filter } from 'rxjs/operators/filter';
    import { map } from 'rxjs/operators/map';
    

    These usually come in the stream after the Observable is created. Like flatMap in this code snippet:

    Observable.of([1,2,3,4])
              .flatMap(arr => Observable.from(arr));
    

    Other such keywords using this syntax:

    audit, buffer, catch, combineAll, combineLatest, concat, count, debounce, delay, 
    distinct, do, every, expand, filter, finally, find , first, groupBy,
    ignoreElements, isEmpty, last, let, map, max, merge, mergeMap, min, pluck, 
    publish, race, reduce, repeat, scan, skip, startWith, switch, switchMap, take, 
    takeUntil, throttle, timeout, toArray, toPromise, withLatestFrom, zip
    

    FlatMap: flatMap is alias to mergeMap so we need to import mergeMap to use flatMap.


    Note for /add imports :

    We only need to import once in whole project. So its advised to do it at a single place. If they are included in multiple files, and one of them is deleted, the build will fail for wrong reasons.