1

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.

1
  • Are you using httpClient module? Commented May 23, 2018 at 9:26

3 Answers 3

1

please see below -

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( ( res ) => {
      return res || {};
    } )
    .catch( this.handleError );
}



handleError(response: any) {
    if (response.status === 401 || response.status === 403) {
        this.tokenService.deleteToken();
        this.router.navigate(['login']);
    }
    // Show popup etc.
    ...
}
Sign up to request clarification or add additional context in comments.

Comments

0
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);
        }););

Comments

0

http.request returns an Observable by default, but you are converting it to a Promise with .toPromise()

Simply change the signature of the function to return Observable<any> and remove the part where you convert the Observable to a Promise (.toPromise().catch((res) => this.handleError(res))).

You'll also need to change the way you listen to the response (you'll most likely have a then where you invoke your service method, you need to change that to a subscribe, which is essentially the equivalent version for Observables).

See this answer for a detailed explanation on how to properly catch exceptions while using Observables.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.