Deniss M.
Deniss M.

Reputation: 4050

Angular & TypeScript: Class instance check doesn't work

I'm trying to check the type of error that is being returned from the web service. The problem is that instanceof check doesn't work. None of the if work.

Component class method that triggers the call to WS:

public performSearch(keyword: string) {
    this.searchService.searchWithQuery(keyword)
      .subscribe(
        response => {
          this.searchResults = JSON.parse(response._body);
        },
        (error: AppError) => {
          console.log('error instance');
          console.log(error);
          if (error instanceof NotFoundError) {
            this.snackBar.open('404 Not Found', 'X', {
              duration: 5000,
            });
          }
          if (error instanceof AccessDeniedError) {
            this.snackBar.open('401 Access Denied', 'X', {
              duration: 5000,
            });
          }
          if (error instanceof BadInputError) {
            this.snackBar.open('400 Bad Input', 'X', {
              duration: 5000,
            });
          }
          if (error instanceof AppError) {
            this.snackBar.open('General Error', 'X', {
              duration: 5000,
            });
          }
        });
  }

search.data.service class that is extending the base service class:

searchWithQuery(query: string) {
    let headers = new Headers();
    headers.append('Authorization', 'Bearer ' + this.tokenValue);
    return this.http.get(this.gatewayUrl + this.serviceName + this.withQuery + query, {
      headers: headers
    })
      .catch(this.handleError);
  }

  private handleError(error: Response): ErrorObservable {
    if (error.status === 404)
      return Observable.throw(new NotFoundError(error.json()));
    if (error.status === 400)
      return Observable.throw(new BadInputError(error.json()));
    if (error.status === 401) {
      return Observable.throw(new AccessDeniedError(error.json()));
    }

    return Observable.throw(new AppError(error.json()));
  }

AppError.ts class

export class AppError {
  constructor(public originalError?: any) {
  }
}

And the rest of the error classes just extend it, f.e.:

export class AccessDeniedError extends AppError {
}

When I am trying to log the error of AppError I get this in the console which is very odd:

TypeError: __WEBPACK_IMPORTED_MODULE_2_rxjs_Observable__.Observable.throw is not a function
    at CatchSubscriber.webpackJsonp.../../../../../src/app/common/services/search.data.service.ts.SearchDataService.handleError [as selector] (search.data.service.ts:52)
    at CatchSubscriber.webpackJsonp.../../../../rxjs/operator/catch.js.CatchSubscriber.error (catch.js:104)
    at XMLHttpRequest.onLoad (http.es5.js:1231)
    at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:424)
    at Object.onInvokeTask (core.es5.js:3881)
    at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:423)
    at Zone.webpackJsonp.../../../../zone.js/dist/zone.js.Zone.runTask (zone.js:191)
    at ZoneTask.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneTask.invokeTask [as invoke] (zone.js:498)
    at invokeTask (zone.js:1370)
    at XMLHttpRequest.globalZoneAwareCallback (zone.js:1388)

Upvotes: 1

Views: 469

Answers (1)

Estus Flask
Estus Flask

Reputation: 222369

As error message says, the error is none of the above but TypeError, and it is caused by the fact that there's no Observable.throw method.

Unless the entire RxJS package was imported with import 'rxjs/Rx', throw should be imported explicitly, as any other RxJS operator or observable method:

import 'rxjs/add/observable/throw';

This kind of errors is supposed to be detected during TypeScript compilation, so there would be no need to debug them at runtime.

Upvotes: 2

Related Questions