angulartypescriptrxjsngrxangular2-observables

Getting "is not a function " errors with RxJS


Seemingly out of the blue I am getting errors with RxJS.

My project is Angular, Typescript and I use RxJS as part of NGRX redux.

My code seemed to work absolutely fine with just this as an import:

import { Observable } from 'rxjs/Observable'

Then, from nowhere I started getting errors like this...

Uncaught (in promise): TypeError: this.appStateStore.withLatestFrom is not a function Uncaught (in promise): TypeError: this.appStateStore.take is not a function

I was able to solve the error about withLatestFrom by adding an import of import 'rxjs/add/operator/withLatestFrom'; but then the error moved to complaining about .take.

I'm guessing I have an import wrong somewhere as I understand with RxJS you need to import the bits that you need. However I've reviewed my source control changes and I can't see that any changes (e.g. node module version, import statements) that would cause this to just start happening.

What I am doing wrong?


Solution

  • import 'rxjs/add/operator/distinctUntilChanged'; 
    import 'rxjs/add/operator/take;
    

    Rxjs v 5.4.1

    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/__________';

    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/_________';

    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.