rxjs: TypeError: Observable.of is not a function since rxjs 6.3.0

After updating rxjs from version 6.2.x to version 6.3.0, the following:

import 'rxjs/add/observable/of';
// or 
import { Observable } from 'rxjs/Observable';

Observable.of(...)

Are not working anymore. The only way to make it work now is by using:

import { of } from 'rxjs/observable/of';

of(...)

is this a bug or the intended behaviour? It looks a breaking change to me 😦

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 30
  • Comments: 56 (8 by maintainers)

Commits related to this issue

Most upvoted comments

This is what I did:

  • ng update

  • ng update @angular/core -> reiterate with the different modules that the previous command shows

  • npm update --save (in order to update the modules which are not managed through ng update)

  • npm list rxjs (in order to see the rxjs dependencies, you should have rxjs 6.3.2 on all core modules and this is what we expect to change)

  • npm un --save rxjs

  • npm un --save rxjs-compat

  • npm list --depth=0 (in order to check that rxjs is removed, you should have a warning or an error at the end of the list)

  • npm i --save rxjs@6.2.2

  • npm i --save rxjs-compat@6.2.2

  • npm list rxjs (check that the previous dependencies have been changed with 6.2.2)

That’s all for me. Of course, if you perform a

rm -rf node_modules

and then a

npm i --unsafe-perm

==> you will reinstall rxjs 6.3.2 due to the angular current dependencies…

Force or reinstall exact version of rxjs@6.2.2 and rxjs-compat@6.2.2.

We also hit that issue this afternoon when some coworker restarted their node_modules from scratch. Setting the version in package.json to force the usage of 6.2.2 fixed the issue. Unfortunately, we cannot drop usage of rxjs-compat package because we have external dependencies relying on it. otherwise, it would have fixed the issue. So basically anybody hitting this have 2 options :

  1. Force the previous version which is 6.2.2
  2. Drop rxjs-compat and do the full migration to 6.x.y according you don’t have any external dependencies that rely on it by following this page: https://rxjs-dev.firebaseapp.com/guide/v6/migration

import Observable from rxjs instead of rxjs/Observable. Also for static methods like of, zip, import static function from rxjs with the method name. It’s more like rxjs-6 way.

āœ“ import { Observable } from 'rxjs'; āœ“ import { zip } from 'rxjs'; āœ“ import { zip as observableZip } from 'rxjs'; āœ— import { Observable } from 'rxjs/Observable';

Analysis of Cause

Angular-cli uses a resolve alias for module rxjs/Observable internally while building, mapping it to rxjs-compat/_esm5/Observable. This mapping is provided by rxjs itself. see Build and Treeshaking for more information. Find angular-cli including the path-mapping here.

Prior to v6.3.0, rxjs-compact/_esm5/Observable exports Observable from rxjs, and when webpack resolves rxjs, it takes the value of key module in rxjs’ package.json as entry point. See resolve.mainFields for more information. For v6.2.2 the module value is rxjs/_esm5/index.js, so the exported Observable object is from rxjs/_esm5/index.js. But, released in v6.3.0, commit https://github.com/reactivex/rxjs/commit/3f75564 changed the import path of Observable from rxjs to rxjs/internal/Observable, causing webpack not to honor the module value in package.json anymore and directly import Observable from rxjs/internal/Observable. The correct resolved path should be rxjs/_esm5/internal/Observable.

Possible solutions for rxjs project itself, would be to add rxjs/internal/Observable to its path-mapping file, mapping it to rxjs/_esm5/internal/Observable, or revert https://github.com/reactivex/rxjs/commit/3f75564 . For users please consider migrate your pre-rxjs6 code to latest. For angular users, if you insist, I have a workaround for you. Add the following snippet to your src/tsconfig.app.json:

{
    "compilerOptions": {
        "paths": {
            "rxjs/internal/Observable": [
                "../node_modules/rxjs/_esm5/internal/Observable"
            ]
        }
    }
}

Please remove this workaround after you finish rxjs 6 migration on your project. It may not work for future versions.

@benlesh: Minimal reproduction:

with angular cli 6.2.4

  1. ng new reproduction
  2. cd reproduction
  3. edit package.json to add rxjs: ā€œ6.3.3ā€ and rxjs-compat ā€œ6.3.3ā€
  4. npm install
  5. edit main.ts to add:
import { Observable } from "rxjs/Observable";
import "rxjs/add/observable/of";

Observable.of(null);
  1. ng serve
  2. localhost:4200 check devtools console
Uncaught TypeError: rxjs_Observable__WEBPACK_IMPORTED_MODULE_4__.Observable.of is not a function

@angular-devkit/build-angular@0.8.1 did not fix the issue for me. Also tried 0.8.3 The package.json "resolutions": { "**/rxjs": "6.3.2" } trick did not seem to change the resolved rxjs transitive versions in package-lock.json Many sub-dependencies still use "rxjs": "~6.2.0"

So downgrading to rxjs@6.2.2 is the only solution that works for me.

Sidenote: ng update @angular/core does bump RxJS to 6.3.2 So IMO this issue is fairly important to fix

Fixed by enforcing 6.3.2 for all dependencies.

Add to package.json

  "resolutions": {
    "**/rxjs": "6.3.2"
  },

Agreed. Full migration would be the answer… but since we’re just making the upgrade to latest Angular v6 and getting everything working (including fixing unit tests that are breaking after the update), adding that just yet isn’t in the cards.

But isn’t the fact that we’re using rxjs-compat mean that we don’t have to change our imports (as in the sample in the original issue description)? I shouldn’t have to change all the imports until we migrate and don’t need rxjs-compat (?)

Import : import { of as observableOf} from ā€˜rxjs’;

and Change Observable.of to observableOf

Instead of import ā€˜rxjs/add/observable/of’;

Below works for me import { of } from ā€˜rxjs’;

Force or reinstall exact version of rxjs@6.2.2 and rxjs-compat@6.2.2.

This one is worked for me as well. Thanks šŸ‘ :

@benlesh And the reason has to do with this change:https://github.com/ReactiveX/rxjs/commit/3f755640ab0214d17cb16318fdd29a3a35ff8093

rxjs-compat 6.2.2

Observable.js

export { Observable } from 'rxjs';

add/observable/of.js

import { Observable, of as staticOf } from 'rxjs';
Observable.of = staticOf;

rxjs-compat 6.3.3

Observable.js

export { Observable } from 'rxjs/internal/Observable';

add/observable/of.js

import { Observable, of as staticOf } from 'rxjs';
Observable.of = staticOf;

add/observable.of.js is the same as in 6.2.2. So there is a mismatch in 6.3.3 the of is not applied to the Observable imported in typscript with import {Observable} from "rxjs/Observable";

I do not know enough about this solution to know why this is, since the observable exported from Observable.js is also the ā€œinternalā€ one…

I encountered this issue while migrating an application from angular 4 to angular 6. I’m still in the process of weeding out other issues but so far I have resolved this one in my package.json (I may encounter a different solution and submit a newer solution in the future):

"dependencies" : {
  ...
  "rxjs" : "6.3.2",
  "rxjs-compat": "6.3.2",
  ...
},
"devDependencies" : {
  @angular-devkit/build-angular": "0.7.0"
  ...
}

Both of these works

  1. Downgrading rxjs npm uninstall rxjs rxjs-compat npm install rxjs@6.2.2 rxjs-compat@6.2.2 --save --save-exact
  2. or upgrading to npm install --save-dev @angular-devkit/build-angular@0.8.1 like @federicopenaranda ( Was able to keep rxjs and rxjs-compat at 6.3.2 )

I’ve updated @angular-devkit from 0.7.5 to 0.8.1 and it solved the problem, with the command npm install --save-dev @angular-devkit/build-angular@0.8.1

I have the same error but only during running ng build ui-components which is my library project stored in projects folder. Running ng build --prod for a application itself works good.

$ ng build ui-components --prod
Building Angular Package
sink._addParentTeardownLogic is not a function
TypeError: sink._addParentTeardownLogic is not a function
    at Observable.subscribe (/Users/jakob/xxx/swagger-xfmr-js/node_modules/@angular-devkit/build-ng-packagr/node_modules/rxjs/internal/Observable.js:27:18)

Some ideas?, yesterday it was working, today I run rm -rf node_modules yarn.lock &&Ā yarn install and i have this.

@anandvr27 I cannot provide you more unfortunately. Try first to remove rxjs, perform a npm list --depth=0 in order to check that rxjs is not installed and then reinstall the 6.2.2 version. You should do the same with rxjs-compat if you’re migrating. I don’t use rxjs-compat anymore.

@skonx i followed the steps given by you, but its not updated to 6.2.2 in all levels. npm list rxjs shows ±- @angular-devkit/build-angular@0.6.8 | ±- @angular-devkit/architect@0.6.8 | | -- rxjs@6.2.0 | +-- @angular-devkit/core@0.6.8 | | – rxjs@6.2.0 | -- rxjs@6.2.0 +-- @angular/cli@6.1.5 | +-- @angular-devkit/architect@0.7.5 | | – rxjs@6.3.2 deduped | ±- @angular-devkit/core@0.7.5 | | -- rxjs@6.3.2 deduped | +-- @angular-devkit/schematics@0.7.5 | | +-- @angular-devkit/core@0.7.5 | | | – rxjs@6.3.2 deduped | | -- rxjs@6.3.2 | +-- @schematics/angular@0.7.5 | | – @angular-devkit/core@0.7.5 | | -- rxjs@6.3.2 | +-- @schematics/update@0.7.5 | | +-- @angular-devkit/core@0.7.5 | | | – rxjs@6.3.2 deduped | | -- rxjs@6.3.2 | – rxjs@6.3.2 `-- rxjs@6.2.2

i tried clearing the npm cache and removing the nodemodules. Nothing worked. Can you please let me know how to reset this? thanks!

Yes. maybe not literally but I’ve tried: npm install --save rxjs/rxjs-compat@6.2.2 --force npm cache clean --force delete node_module and npm install…

I have tried several things, also reinstalling 6.3.2…maybe I have not done something completely correctly, I am a beginner

Anyone tested this with rxjs/rxjs-compat 6.3.1?

for me switching back to 6.2.1 solves the issue