Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 4. A series of http requests get cancelled

Tags:

When I try to make multiple http requests via http service in Angular 4, previous request get cancelled in Chrome (but they reach the server). Example:

const obs1 = this.http.get(`${API_URL}/transitions`); const obs2 = this.http.get(`${API_URL}/states`); obs1.subscribe();   obs2.subscribe(); // this will cancel obs1's http request 

But if I replace .subscribe() to .publish().connect() like above, it will work correctly (no cancels)

const obs1 = this.http.get(`${API_URL}/transitions`); const obs2 = this.http.get(`${API_URL}/states`); obs1.publish().connect(); obs2.publish().connect(); 

Or if I merge two Observables to one and then get subscribed like above, it will work correctly too

const obs1 = this.http.get(`${API_URL}/transitions`); const obs2 = this.http.get(`${API_URL}/states`); Observable.merge(obs1, obs2).subscribe() 

Why do I face this behavior? I need to understand, not bypass. How can I make series of requests without merging, forking etc.?

like image 970
egorgrushin Avatar asked Aug 23 '17 15:08

egorgrushin


People also ask

Why HTTP request gets cancelled?

If a site such as https://www.example.com is misconfigured such that the certificate does not include the www. but is valid for https://example.com , chrome will cancel this request and automatically redirect to the latter site. This is not the case for Firefox.

Can HTTP request be Cancelled?

We can use the AbortController object and the associated AbortSignal with the Fetch API to make cancelable HTTP requests. Once the AbortSignal is sent, the HTTP request is canceled and won't be sent if the cancellation signal is sent before the HTTP request is done.

What is HTTP request and response in angular?

The asynchronous method sends an HTTP request, and returns an Observable that emits the requested data when the response is received. The return type varies based on the observe and responseType values that you pass to the call.

How to cancel HTTP requests in AngularJS?

How to Cancel HTTP Requests in AngularJS 1 The Problem in Promise Chain. AngularJS provides a easy way to cancel an HTTP request. $http accepts a timeout option... 2 Under the Hood. We can see that the old promise has a reference ( this.$$state.pending [0] [0] ) to the new promise. 3 Implementation. More ...

How difficult is it to cancel an ongoing HTTP request?

Recently we need to make a new feature that allows users to cancel an ongoing HTTP request. This is a fairly reasonable requirement and technically not difficult to implement, however, our architecture, which consists of AngularJS and ngRedux, makes it more challenging.

Which version of angular is this post compatible with?

This Angular post is compatible with Angular 4 upto latest versions, Angular 7, Angular 8, Angular 9, Angular 10, Angular 11, Angular 12 and Angular 13 In this tutorial, we will get to know how to cancel unnecessary HTTP get, post or any request to server after a user route to another component in an application using Angular Interceptor services.

How to cancel the HTTP request when timeout promise is resolved?

The HTTP request will be cancelled when the timeout promise is resolved. Here is an example: In above snippet, we can easily cancel the HTTP request by calling canceller.promise.resolve (). However the problem is obvious: canceller is not returned in fetchBooks ().


2 Answers

This has to do with observables being cancelled, although I must admit I don't know the root cause for the problem you face.

I ran into a similar problem using the ngrx/effects module. The action handler made requests to a service using ngrx switch map operator. All except the last request would get cancelled. Changing it to merge map fixed the problem. Below is the code

@Effect()     loadSomeData$: Observable<Action> = this.actions$             .ofType(SomeActions.Load_Data)             .mergeMap((id) =>                     this.someService.getSomething(id)                             .map((someEntity) => new SomeActions.LoadDataSuccess(someEntity)                             ).catch((x, y) => {                                     console.error('Error occured');                                     return Observable.of(new SomeActions.LoadDataFailed(id));                             }                             )); 

Reproducing the relevant part of ngrx here.

https://www.learnrxjs.io/operators/transformation/switchmap.html

The main difference between switchMap and other flattening operators is the cancelling effect. On each emission the previous inner observable (the result of the function you supplied) is cancelled and the new observable is subscribed. You can remember this by the phrase switch to a new observable.

like image 79
Mahesh Avatar answered Sep 28 '22 00:09

Mahesh


For me the problem was because of an empty observable. I was using Observable.forkJoin on a list of observables.

SOLUTION: I needed to give my Observable.of() a value: Observable.of(null)

like image 39
Kevin Upton Avatar answered Sep 27 '22 22:09

Kevin Upton