8

I am following some Rx.Observable tutorials from an Angular 2 application and using an AutoComplete style of system.

As I type into a field, the valueChanges event fires from the Angular 2 FormControl.

This is chained through to Observable that is making a HTTP request against a JSON endpoint.

The moment the endpoint returns a 404 Status, the valueChanges event stops working.

I can see the error in my subscribe method, but not really sure what the best technique is to recover and keep going.

I am also a little confused why the KeyUp or ValueChange event would stop firing.

Sample Value Change - Observable Chain

this.userNameControl
    .valueChanges
    .do(r => {
            // As soon as a 404 status is thrown from getGitHuybUser$, all value change (keyup) events stop working
            console.log
        }
    )
    .switchMap(userName => {
        return this.getGitHubUser$(userName);
    })
    .catch(err => {
        return Observable.of(err)
    })
    .subscribe(v => {
            console.log(v);
        },
        (err) => {
            // As soon ass there is a 404 status, I end up here
            console.log(err);
        },
        () => {
            console.log('Complete');
        });

getGitHubUser$(username) {
    return this.http
        .get(`https://api.github.com/users/${username}`)
}

HTML Form Control

<input type="text" [value]="userName" [formControl]="userNameControl" />

I tried returning Observable.empty() and Observable.never() in the catch

.catch(err => {
    // Observable.of(err)
    // return Observable.empty();
    return Observable.never();
})

And the result was that the subscribe method called my complete method and still and so the valueChanges still do not fire.

David Cruwys
  • 6,262
  • 12
  • 45
  • 91
  • 1
    A subscription finishes as soon as there is an error. You have to either filter out the error and retry somehow, or resubscribe. – Bob Dalgleish Dec 21 '16 at 22:11

1 Answers1

6

Figured out my issue, the .catch() that I had hanging of the .switchMap() really needed to be hanging of the this.getGitHubUser$(userName)

this.userNameControl
    .valueChanges
    .do(r => {
            // As soon as a 404 status is thrown from getGitHuybUser$, all value change (keyup) events stop working
            console.log(r);
        }
    )
    .switchMap(userName => {
        console.log('GET GIT HUB USER');

        return this.getGitHubUser$(userName)
            .catch(err => {
                console.log('CATCH INNER');
                console.log(err);
                return Observable.of(err)
            })
    })
    // .catch(err => {
    //     // THIS CODE IS NOT NEEDED
    //     console.log('CATCH');
    //     console.log(err);
    //     return Observable.never(); // Observable.of(err)
    // })
    .subscribe(v => {
            console.log('SUCCESS');
            console.log(v);
        },
        (err) => {
            console.log('ERROR');
            console.log(err);
        },
        () => {
            console.log('COMPLETE');
        });
David Cruwys
  • 6,262
  • 12
  • 45
  • 91
  • 1
    PS. Your solution fixed my problem but i don't undertand. I had a similar problem, but in my case i wasn't using the catch at all, I was just using the 2nd argument in subscribe to handle the error. It worked fine for the first event i.e first change in value. But didn't work subsequently after the error had occured. Do you know the precise reason why this is happens? – nissim_dev Sep 25 '17 at 10:17
  • 2
    Error handler in the subscriber works as completion, so the the observable stops working. This is by design. If you want you observable to keep emitting despite errors, you have to handle the errors in a catch block and emit Observable of something that is not error. – Looted Jan 26 '18 at 15:14