Search code examples
angularrxjsangular2-servicesrxjs5angular2-observables

How to handle HTTP errors in API service and return response through Observable only in case of success?


In my Angular2 app I have an api.service with method sendRequest that should do following:

  1. Sends request to the server
  2. Returns promise to the caller (I want callers to get success responses only)
  3. If error occured handle the error localy (navigate user to login or show a popup)

I implemented it using Promise:

sendRequest(method: string, url: string, data: any) : Promise<any> {
    return this.http.request(method, url, {
        body: data,
        headers: {
            'Accept': 'application/json, text/plain, */*',
            'Authorization': 'bearer ' + token,
            'Content-Type': 'application/json;charset=UTF-8'
        }
    }).toPromise().catch((res) => this.handleError(res));
}

handleError(response: any) {
    if (response.status === 401 || response.status === 403) {
        this.tokenService.deleteToken();
        this.router.navigate(['login']);
    }
    // Show popup etc.
    ...
}

I'd like to replace promise by observable:

sendRequest(method: string, url: string, data: any) : Observable<any> {...}

Please advise how to do that. Thank you.

EDIT 1: I found examples that handled response and then passed some result to the observer. That's not what I need. If error occurs the observer shouldn't be notified at all. Observers should be notified only if a successful response arrived. If error occurs it should be processed inside api.service only.


Solution

  • sendRequest(method: string, url: string, data: any) : Observable<any> {
        return this.http.request(method, url, {
            body: data,
            headers: {
                'Accept': 'application/json, text/plain, */*',
                'Authorization': 'bearer ' + token,
                'Content-Type': 'application/json;charset=UTF-8'
            }
        }).map((response: Response) => <any>response.json()).catch(this.handleError);
    }
    
    handleError(response: any) {
        if (response.status === 401 || response.status === 403) {
            this.tokenService.deleteToken();
            this.router.navigate(['login']);
        }
        // Show popup etc.
        ...
    }
    
    //get response like below
      this.yoursevice.sendRequest(resdata)
            .subscribe((resdata) => {}, 
    (error) => {
                this.statusMessage =
                    'Problem with the service. Please try again after sometime';
                console.error(error);
            }););