Search code examples
angularrxjsangular-httpclient

Angular 2 - Shared Observable - second subscribe error callback fails


We have a component that handles view management and a service that manages server interaction and data parsing.

The service postForm method returns a shared observable to the component. The service subscribes to it and the component does.

On success, the service callback method does some data stuff Also on success or error the component callback updates feedback in the view.

Problem: The component error callback only fires if the service subscribe function includes an error callback.

Am I using a bad pattern? If not why do I need error callbacks in both subscribe functions to get the component one to work?

Thanks

Component:

    onSubmit(): void {
    this.service.postForm().subscribe(
        () => this.onSuccessfulPost(),
        ()=>this.onErrorPost()
    );
}

Service:

    postForm() {

    //Code here assembles url and body variables

    this.currentObservable = this.http.post(url, body)
        .map((response: Response) => this.parseResponse(response))
        .catch((err: Response) => this.onHttpError(err)).share();
    this.currentObservable.subscribe(
        (response: any) => this.onSuccessfulPost(response),
        () => {return}  //WITHOUT THIS LINE COMPONENT CALL FAILS
    );
    return this.currentObservable;
}

Solution

  • I'm not sure why it does not work without the error callback, the two observers should be independent of each other. But pattern-wise, I would avoid subscribing in the service and leave the subscribe to the component. If you need to do some logic in the service that is independent of the response, then you can use the do operator.

    postForm() {
        //Code here assembles url and body variables
    
        this.currentObservable = this.http.post(url, body)
            .map((response: Response) => this.parseResponse(response))
            .catch((err: Response) => this.onHttpError(err))
            .do(response => this.onSuccessfulPost(response));
        return this.currentObservable;
    }
    

    Since you only have 1 observer (subscriber), you do not need the share anymore