Getting "is not a function " errors with RxJS
Asked Answered
K

2

5

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?

Krypton answered 4/9, 2017 at 10:36 Comment(1)
Then add import 'rxjs/add/operator/distinctUntilChanged'; import 'rxjs/add/operator/take';Vertigo
P
21
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.

Presnell answered 4/9, 2017 at 11:8 Comment(0)
M
0

If someone lands here with the usage of mergeMap, concatMap, exhaustMap or switchMap, just like I did, you probably missed to add the arrow function part

() =>

This will work :

mergeMap(() => this.loginForm.valueChanges.pipe()),

This one will give you an error :)

ERROR TypeError: project is not a function

mergeMap(this.loginForm.valueChanges.pipe()),
Mihrab answered 23/4, 2024 at 16:13 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.