42

I'm migrating an Angular 5 app to the latest CLI and Angular 6 RC and all of my Observable imports are broken. I see that Angular 6 changes the way the imports work, but I can't find any definite reference as to how the syntax works.

I had this in 5 and it worked fine:

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';

Now with the new syntax I see that

import { Observable, Subject, throwError} from 'rxjs';
import { map } from 'rxjs/operators';

The first two lines compile, but I can't figure out how to get catch and throw for example. .map() also throws a build error when used in code.

Anybody have a reference to how this is supposed to work?

Rick Strahl
  • 17,302
  • 14
  • 89
  • 134
  • 1
    Not sure if that's what you ask for, but you need to refactor the code itself, if you haven't already done. There is the new `pipe` syntax. Something like e.g. `yourObservable$.pipe(map(val => val * 2)).subscribe()`. So with this kind of import you won't use `yourObservable$.map(blah)`. Here's some reference: https://blog.angularindepth.com/rxjs-understanding-lettable-operators-fe74dda186d3 – Radosław Roszkowiak Apr 13 '18 at 07:13
  • 1
    See https://github.com/ReactiveX/rxjs/blob/master/doc/pipeable-operators.md – jonrsharpe Apr 13 '18 at 07:21

5 Answers5

24

From rxjs 5.5, catch has been renamed to catchError function to avoid name clash.

Due to having operators available independent of an Observable, operator names cannot conflict with JavaScript keyword restrictions. Therefore the names of the pipeable version of some operators have changed.

import { catchError } from 'rxjs/operators';

For throw you can use ErrorObservable.

import { ErrorObservable } from 'rxjs/observable/ErrorObservable';
ErrorObservable.create(new Error("oops"));

rxjs 6

Instead of ErrorObservable use throwError.

 import { throwError } from 'rxjs'
 throwError(new Error("oops"));

Also you will now have to pipe the operators instead of directly chaining them to the observable

Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
  • throw has a new name now i.e. throwError and you can import it like so: **import { throwError } from 'rxjs';** – rgantla May 08 '18 at 20:24
  • Doesn't importing it from 'rxjs' bring over the whole module? What is the more specific path for the import? – Saturn K Jul 27 '18 at 23:10
  • @KeyvanSadralodabai not in the case of rxjs v6. Apparently they have been changed according to [this](https://github.com/ReactiveX/rxjs/blob/master/docs_app/content/guide/v6/migration.md#import-paths) – Suraj Rao Jul 28 '18 at 04:52
11

Pipes are what is required for operator(s) going forward.

version: rxjs 6.0.1

Example:

import { Observable } from "rxjs";
import { map } from "rxjs/operators";

Observable.create((observer: any) => {
    observer.next('Hello')
}).pipe(map((val: any) => val.toUpperCase()))
  .subscribe((x: any) => addItem(x))


function addItem(val: any) {
    console.log('val', val);
}

//output - (In uppercase)
HELLO
Dash
  • 717
  • 6
  • 10
6

Run these 2 commands after running ng update. This should fix the rxjs imports:

  1. npm i -g rxjs-tslint
  2. rxjs-5-to-6-migrate -p src/tsconfig.app.json

References:

kvetis
  • 6,682
  • 1
  • 28
  • 48
  • 1
    How does one get `rxjs-5-to-6-migrate` into a PATH variable? After I run `npm i -g rxjs-tslint`, and then run `rxjs-5-to-6-migrate` I get `rxjs-5-to-6-migrate is not recognized as an internal or external command` – jaycer May 15 '18 at 20:32
5

Or if you want to keep using version 6.0.0 you do

npm i --save rxjs-compat

to add reverse compatibility

Pian0_M4n
  • 2,505
  • 31
  • 35
0

You just need to import like operators

import { Observable } from 'rxjs';
import { map, catchError, timeout } from 'rxjs/operators';
Matt
  • 1,518
  • 4
  • 16
  • 30
vishal
  • 137
  • 1
  • 7