6

What is the "best" (common) way to make sure that my Angular HTTP request only returns the newest response data. (I am using Angulars HttpClient)

Lets say the user submits a new request before the response of the previous request is returned. My backend needs more time to process the first request so the second request returns before the first one -> the view get's updated and later the first request returns. Now the view gets updated with old data. Thats obviously not what I want.

I found this solution to cancel the request but is that really the only way? Are there any build in functionalities to achive that?

if ( this.subscription ) {
   this.subscription.unsubscribe();
}
this.subscription = this.http.get( 'myAPI' )
 .subscribe(resp => {
  // handle result ...
});

I know there is the switchMap() operator which only returns the latest data but as far as I know you can only use it inside of an observable. In my case I am not observing any input changes. I simply call a function on form submit via (ngSubmit)="doRequest()" directive in HTML-Template.

// get called on submit form
doRequest() {
 this.http.get('myAPI')
  .subscribe(resp => {
    // handle result ...
  });
}

Is there a way to use the switchMap operator or do you have any other solutions? Thanks for taking your time :)

PS: Of course in my real project I have an api service class with different functions doing the requests and just returning http response observables. So I subscribe to such an observable in doRequest() function.

1 Answer 1

7

you just make the clicks / requests a stream that you can switch off of... the user's requests / clicks are a stream of events that you can observe and react to.

private requestSource = new Subject();

request() {
  this.requestSource.next();
}

ngOnInit() {
  this.requestSource.switchMap(req => this.http.get('myApi'))
                       .subscribe(response => console.log(response, "latest"));
}

modern client programming rule of thumb: everything is a stream, even if it doesn't look like one right away.

Edit: In the case of rxjs 6 or latest version, add pipe operator with the above code.

this.requestSource.pipe(switchMap(...));
Sign up to request clarification or add additional context in comments.

3 Comments

I just have to add the pipe operator since I am using rxjs 6. So this.requestSource.pipe(switchMap(...)); is working for me. Thank you!
I found a problem doing it this way. If my server request fails and my http observable returns an error calling this.requestSource.next(); doesn't do anything anymore. Is there a workaround for that?
you need to handle your errors with either the error handler in the subscribe method or the catch operator

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.