How to throw observable error manually in angular2?

蹲街弑〆低调 提交于 2019-11-27 00:56:23

问题


I am working on angular2 app in which I am making a rest call through HTTp as below:

login(email, password) {
    let headers = new Headers();
    headers.append('Content-Type', 'application/x-www-form-urlencoded');
    let options = new RequestOptions({ headers: headers });
    let body = `identity=${email}&password=${password}`;
    return this.http.post(`${this._configService.getBaseUrl()}/login`, body, options)
    .map((res: any) => {
        let response: any = JSON.parse(res._body);
        if (response.success == 0) {
          Observable.throw(response);  // not working
        } else if (response.success == 1) {
          console.log('success');
          localStorage.setItem('auth_token', 'authenticated');
          this.loggedIn = true;
          return response;
        }
    });
}

basically I want my component to get response & error in my subscribe call.

i.e.

this._authenticateService.login(this.loginObj['identity'],this.loginObj['password']).subscribe(
  (success)=>{      
    this.credentialsError=null;  
    this.loginObj={};  
    this._router.navigate(['dashboard']);    
  },
  (error)=>{
    console.log(error);        
    this.credentialsError=error;     
  }
);

but my api always returns success as it id defined that way.

So I want to know how can I throw error msg if response.success == 0 , so that it will be accessed inside error argument of my subscribe callback.


回答1:


if (response.success == 0) {
   throw Observable.throw(response);  
 } 

Edit for rxjs 6:

if (response.success == 0) {
   throw throwError(response);  
 } 



回答2:


rxjs 6

import { throwError } from 'rxjs';

if (response.success == 0) {
  return throwError(response);  
}

rxjs 5

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

if (response.success == 0) {
  return new ErrorObservable(response);  
}

What you return with ErrorObservable is up to you




回答3:


with rxjs 6

import { throwError } from 'rxjs';
throwError('hello');



回答4:


rxjs 5

Either

throw response;

or

throw Observable.throw(response);



回答5:


Use the catch operator

this.calcSub = this.http.post(this.constants.userUrl + "UpdateCalculation", body, { headers: headers })
   .map((response: Response) => {
      var result = <DataResponseObject>response.json();
         return result;
   })
   .catch(this.handleError)
   .subscribe(
      dro => this.dro = dro,
      () => this.completeAddCalculation()
   );

And handle the error like this:

private handleError(error: Response) {
    console.error(error); // log to console instead
    return Observable.throw(error.json().error || 'Server Error');
}



回答6:


Most of my issues were related to the imports, so here's the code that worked for me...

import {_throw} from 'rxjs/observable/throw';
login(email, password) {
...
    return this.http.post(`${this._configService.getBaseUrl()}/login`, body, options)
    .map((res: any) => {
...
        if (response.success == 0) {
           _throw(response);  
        } else if (response.success == 1) {
...
        }
    });
}

This will be the solution if you are facing errors like...

ERROR TypeError: WEBPACK_IMPORTED_MODULE_2_rxjs_Observable.Observable.throw is not a function




回答7:


Usually when you're throwing an error you'll be doing so at the exact moment the problem occurred and you want to raise it immediately, but this may not always be the case.

For instance there is the timeoutWith() operator, which is perhaps one of the most likely reasons you'll need to do this.

results$ = server.getResults().pipe(timeoutWith(10000, ....) )

This takes an 'error factory', which is a function.

 errorFactory = () => 'Your error occurred at exactly ' + new Date()

eg.

results$ = server.searchCustomers(searchCriteria).pipe(timeoutWith(10000, 
              () => 'Sorry took too long for search ' + JSON.stringify(searchCriteria)) )

Note that when using timeoutWith you'll never get the actual server response back - so if the server gave a specific error you'd never see it. This above example can be very useful in debugging, but be sure not to display the error to the end user if you use the above example.

AN error factory is helpful because it doesn't evaluate the code until the actual error occurs. So you can put 'expensive' or debugging operations inside that will get executed when the error is actually finally needed.

If you need to use a 'factory' to create your error somewhere other than in timeout you can use the following.

 EMPTY.pipe(throwIfEmpty(errorFactory)) 



回答8:


Here is the official example (that emits number 7 and then error 'oops!'):

import { throwError, concat, of } from 'rxjs';

const result = concat(of(7), throwError(new Error('oops!')));
result.subscribe(x => console.log(x), e => console.error(e));

From: https://rxjs-dev.firebaseapp.com/api/index/function/throwError



来源:https://stackoverflow.com/questions/40511948/how-to-throw-observable-error-manually-in-angular2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!