"rxjs" observable.throw is not a function - Angular4

69,208

Solution 1

The error There are multiple modules with names that only differ in casing. is indicating the wrong import is being targeted with how you are trying to use Observable.

The import should be with a capital "O" like:

import { Observable } from 'rxjs/Observable';

This will import the individual Observable operator, which be used in combination with operators such as catch or throw on created Observables.

import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';

To import the full Observable object you'd import it like this:

import { Observable } from 'rxjs/Rx'

Update:

With newer versions of RxJS (5.5+) operators such as map() and filter() can used as pipeable operators in combination with pipe() rather than chaining. They are imported such as:

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

Keep in mind terms such as throw are reserved/key words in JavaScript so the RxJS throw operator is imported as:

import { _throw } from 'rxjs/observable/throw';

Update:

For newer versions of RxJS (6+), use this:

import { throwError } from 'rxjs';

and throw an error like this:

if (error.status === 404)
    return throwError( new NotFoundError(error) )

Solution 2

In RxJS 6, Observable.throw() is replaced by throwError() which operates very similarly to its predecessor. So, you can replace from Observable.throw(error) to only throwError(error) by importing:

import { throwError } from 'rxjs';

Checkout this link for further reference: https://www.metaltoad.com/blog/angular-6-upgrading-api-calls-rxjs-6

Solution 3

I was facing the same issue in my angular 5 application. What I did is, adding a new package.

import { throwError } from 'rxjs';
import { filter, map, catchError } from 'rxjs/operators';

And from my http service call I return a function.

return this.http.request(request)
      .pipe(map((res: Response) => res.json()),
        catchError((res: Response) => this.onError(res)));

And in onError function I am returning the error with throwError(error).

onError(res: Response) {
    const statusCode = res.status;
    const body = res.json();
    const error = {
      statusCode: statusCode,
      error: body.error
    };
    return throwError(error);
  }

Solution 4

_throw has been discarded in newer versions of RxJS
For newer versions of RxJS (6+), use this:

 import { throwError } from 'rxjs'; 

and throw an error like this:

 if (error.status === 404)
    return throwError( new NotFoundError(error) )
Share:
69,208

Related videos on Youtube

nick gowdy
Author by

nick gowdy

Updated on May 04, 2020

Comments

  • nick gowdy
    nick gowdy about 4 years

    I've been learning Angular 4 and everything was going smoothly until I tried to implement catch handling in a service. I'm trying to use "rxjs" catch and throw but I've got an undefined function error in my console.

    import { Injectable } from '@angular/core';
    import { Http } from "@angular/http";
    import { Observable } from 'rxjs/observable';
    import 'rxjs/add/operator/catch';
    import 'rxjs/add/observable/throw';
    import { AppError } from "../app/common/app.error";
    import { NotFoundError } from "../app/common/not-found-error";
    import { BadInput } from "../app/common/bad-input";
    
    @Injectable()
    export class PostService {
      private url = "https://jsonplaceholder.typicode.com/posts";
    
      constructor(private http: Http) { }
    
     deletepost(post){
          // return this.http.delete(this.url + '/' + post.id)
          // Hard-coded id to test 404
          return this.http.delete(this.url + '/' + 93498)
            .catch((error: Response) => {
              console.log('error within catch is ' + Response)
              if(error.status === 404)
                return Observable.throw(new NotFoundError(error));
    
              return Observable.throw(new AppError(error));
            });
        }
    }
    

    This is the error message:

    TypeError: __WEBPACK_IMPORTED_MODULE_2_rxjs_observable__["Observable"].throw is not a function. 
    (In '__WEBPACK_IMPORTED_MODULE_2_rxjs_observable__["Observable"].throw(new 
    __WEBPACK_IMPORTED_MODULE_6__app_common_not_found_error__["a" /* NotFoundError 
    */](error))', 
    '__WEBPACK_IMPORTED_MODULE_2_rxjs_observable__["Observable"].throw' is 
    undefined) — post.service.ts:42
    

    I also have this warning in my browser:

    ./~/rxjs/Observable.js
    There are multiple modules with names that only differ in casing.
    This can lead to unexpected behavior when compiling on a filesystem with other case-semantic.
    Use equal casing. Compare these module identifiers:
    * /Users/nickgowdy/Desktop/Angular2/angular4 source code/hello-world/node_modules/rxjs/Observable.js
        Used by 14 module(s), i. e.
        /Users/nickgowdy/Desktop/Angular2/angular4 source code/hello-world/node_modules/@angular/core/@angular/core.es5.js
    * /Users/nickgowdy/Desktop/Angular2/angular4 source code/hello-world/node_modules/rxjs/observable.js
        Used by 1 module(s), i. e.
        /Users/nickgowdy/Desktop/Angular2/angular4 source code/hello-world/node_modules/@ngtools/webpack/src/index.js!/Users/nickgowdy/Desktop/Angular2/angular4 source code/hello-world/src/services/post.service.ts
    
    • Alexander Staroselsky
      Alexander Staroselsky almost 7 years
      Try importing import { Observable } from 'rxjs/Observable'; with a capital "O" instead of import { Observable } from 'rxjs/observable'; with a lowercase "o" and see if that makes any difference.
    • nick gowdy
      nick gowdy almost 7 years
      @AlexanderStaroselsky Wow I can't believe that was the reason why. I didn't notice that it was higher case O because it doesn't match the naming convention of all the other imported dependencies. You should post this as the answer so I can mark it as correct.
    • Alexander Staroselsky
      Alexander Staroselsky almost 7 years
      I've experienced the same thing, the error doesn't always make it clear. Mind if I put that as an answer so that other experiencing the issue may find a solution?
    • nick gowdy
      nick gowdy almost 7 years
      @AlexanderStaroselsky Yeah go for it. Create an answer for this question and i'll mark it as correct. Thanks for your help.
  • barakbd
    barakbd over 6 years
    Importing the full Observable - import { Observable } from 'rxjs/Rx' - increases bundle size. From the docs: github.com/ReactiveX/rxjs To import only what you need by patching (this is useful for size-sensitive bundling): import { Observable } from 'rxjs/Observable'; import 'rxjs/add/observable/of'; import 'rxjs/add/operator/map';
  • Alexander Staroselsky
    Alexander Staroselsky over 6 years
    Yes, import { Observable } from 'rxjs/Rx'; can significantly add to the bundle size as it's importing the full Observable object. In most cases I'd argue it's just not needed, but I wanted to provide it as an option as each application is different and may need that kind of control.
  • valik
    valik about 6 years
    @AlexanderStaroselsky bless you man helped me a lot, whats the difference beween import {Observable} from "rxjs/Observable and import {Observable} from "rxjs because i had problem with Observable throw(error) it only worked when i removed /Observable at the end
  • Alexander Staroselsky
    Alexander Staroselsky about 6 years
    @valik Without the /Observable it sounds like you are likely importing the full Observable object that includes methods such as throw. Depending on your RxJS version, I'd recommend to avoid importing the full Observable object and instead utilize Pipeable Operators. Angular has documentation demonstrating using RxJS including using catchError to handle errors. Importing the full Observable object brings in stuff you simply may not need.
  • valik
    valik about 6 years
    //import {Observable} from "rxjs/Observable"; import { Observable } from 'rxjs'; this are the two first doesnt work well with private handleError (error: HttpResponse<Truck> | any) { console.error(error.ok || error); return Observable.throw(error.status); }
  • valik
    valik about 6 years
    was not able to observe the status code @AlexanderStaroselsky with first one , but i want to know how to use the first one handle error it simply did not work when i changed i was able to observe my errors
  • Alexander Staroselsky
    Alexander Staroselsky about 6 years
    Observable.throw() is NOT available for import { Observable } from 'rxjs/Observable'; Methods like throw() are available on Observable when importing the full Observable object either through import { Observable } from 'rxjs/Rx'; or simply import { Observable } from 'rxjs';. However you can import { Observable } from 'rxjs/Observable'; then import 'rxjs/add/observable/throw'; and it should work. Check this StackBlitz. I'd also recommend to create a new question to help resolve any specific issues you are having.
  • Stephane
    Stephane about 6 years
    I had to import both import { Observable } from 'rxjs/Observable'; and import 'rxjs/add/observable/throw'; to avoid the error message rxjs observable.throw is not a function.
  • wctiger
    wctiger almost 6 years
    This solution worked in my Angular 6 app w/ rxjs 6.0. My import statement is already import { Observable } from 'rxjs/Observable' , while doing this I still get the Observable.throw is not a function error. I tried import 'rxjs/add/observable/throw' but it gave a compiler error.
  • Karthikeyan Vellingiri
    Karthikeyan Vellingiri over 5 years
    Thanks Sibeesh !!
  • Dinesh Gopal Chand
    Dinesh Gopal Chand over 5 years
    Thank you for sharing detailed information. In my case only import 'rxjs/add/observable/throw'; didn't work. After that I tried both import line import 'rxjs/add/observable/throw'; import { _throw } from 'rxjs/observable/throw'; and it works like a charm
  • catch22
    catch22 over 5 years
    This saved me! This is the new fix
  • adamonstack
    adamonstack over 3 years
    This worked for me. throwError inherits from Observable so it was a straight swap.