2

So I am having a service that does some http API calls...

all the examples I've found online assume the JSON returned is valid...

what I want to do is to trigger the same call as catch block in http

so

getData(id: string): Observable<someEntity>{
    return this.http.get(someUrl)
        .map(this.handleResponse.bind(this))
        .catch(this.handleError);
}

private handleResponse(res: Response){
    if(res.status === 200){
        let body = res.text();
        if(!this.appService.IsJsonString(body)){
            return this.handleError(new Error('The response is not valid JSON '));
        }else{
            return res.json() || {};
        }
    }

}

private handleError (error: any) {
    this.appService.errorAdd(error.status, error.statusText, 'Error loading Index data', ErrorTypes.Data);

    let errMsg = (error.message) ? error.message : error.status ? `${error.status} - ${error.statusText}` : 'Server error';
    return Observable.throw(errMsg);
}

when I do then in my component:

this.myService.getData(someID)
    .subscribe(
        data => {...},
        error => {
            // LOGIC HERE
        }
    );

I want both errors to be handled by // LOGIC HERE (error block).... and not one in the success block and the other in error

What am I doing wrong?

1
  • as I said... I want my component to subscribe and in error block to handle BOTH types of errors (server [code 300+ or < 200]) AND (JSON parsing, or some other validation I could put in [like if the response object has at least 5 rows or something)) Commented Aug 16, 2016 at 15:37

1 Answer 1

2

Changing handleResponse as follow will meet your requirement.

private handleResponse(res: Response){
    if(res.status === 200){
        let body = res.text();
        if(!this.appService.IsJsonString(body)){

            // Throw, instead of return
            throw 'The response is not valid JSON';

        }else{
            return res.json() || {};
        }
    }
}

You can also get rid of private handleError

getData(id: string): Observable<someEntity>{
    return this.http.get(someUrl)
        .map(this.handleResponse.bind(this));
        // Don't catch here
        // Let the subscription error block to handle error throw
        // .catch(this.handleError);
}

If you want to hide RxJs object from component

Change the way getData() is call

getData(
    id: string,
    callback: (result: any) => void,
    errorHandler) {

    this.http.get(someUrl)
        .map(this.handleResponse.bind(this))
        .subscribe(r => callback(r), e=>errorHandler);
}

In component

this.myService.getData(
    someID,
    data => {...},
    error => {
        // LOGIC HERE
    }
);
Sign up to request clarification or add additional context in comments.

2 Comments

nice...looking close to what I want... will have to test it tomorrow... CHEERS!
@DS_web_developer Updated with correct solution. My original answer look good on screen but does not work. :P

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.