angularrxjsobservableangular-httpclientswitchmap

RxJs switchMap with angular HttpClient


I have a use case whenever a new request is triggered, any http requests that are already in flight should be cancelled / ignored.

For eg:

  • A request (say #2) comes in while the request #1 takes too long to respond / slow network connectivity.
  • In this case #2 gets a very quick response from server then at any point even if the #1 comes back with a response the HTTP response observable should be ignored.
  • The problem i face is, first the component displays response values from request #2 and gets updated again when req #1 completes (this should not happen).

I figured that switchMap cancels obervables / maintains the order in which the observable values are emitted.

excerpt from my service.ts

Obervable.of('myServiceUrl')
             .switchMap(url => this.httpRequest(url) )
              .subscribe( response => {
                   // implementation
                   /** Update an observable with the 
                       with latest changes from response. this will be 
                       displayed in a component as async */
                });


private httpRequest(url) {
        return this.httpClient.get('myUrl', { observe: 'response' });
}

The above implementation doesn't work. Could some one figure out the correct implementation for this usecase.


Solution

  • I have the below code excerpt with which the switchMap implementation was successfull.

    class MyClass {
        private domain: string;
        private myServiceUri: subject;
        myData$: Observable<any>;
    
            constructor(private http: HttpClient) {
                .....
                this.myServiceUri = new Subject();
                this.myServiceUri.switchMap(uri => {
                        return this.http.get(uri , { observe: 'response' })
                                // we have to catch the error else the observable sequence will complete
                                .catch(error => {
                                    // handle error scenario
                                    return Obervable.empty(); //need this to continue the stream
                                });
                        })
                        .subscribe(response => {
                            this.myData$.next(response);
                        });
            }
    
            getData(uri: string) {
                this.myServiceUri.next(this.domain + uri); // this will trigger the request     
            }
    
        }