Why web api methods are called multiple times

Viewed 1843

I am calling a web api method as shown below from angular,But web api methods are executed two times.Any idea why it is happening here. I have put a console log in origin ,angular code and confirmed that it is called one time from angular.BUt strange web api methods are executed two times, something like running on thread.

Angular code

 public Createsamples(): Observable<any> {
        var url = this.baseApiUrl + 'Test/Createsamples';
        return this.httpService.post(url, JSON.stringify(obj), { headers: reqHeader, withCredentials: true });
    }

Web api code

 [System.Web.Http.RoutePrefix("api/Test")]
    [EnableCors(origins: "*", headers: "*", methods: "*")]
    public class TestApiController 
    {
       [Route("Createsamples")]
        [System.Web.Http.HttpPost]
        public IHttpActionResult Createsamples()
        {
            TestBO Bo = new TestBO ();
            var result = Bo.Createsamples(obj);
            return Ok(result);
        }
}
2 Answers

You might be dealing with an RxJS side-effect.

Observables are cold and won't do any computation unless there are any subscriptions done to it.

Once you call subscribe or use the observable | async then the computations and Side-Effects kick in (in your case a network request).

In order to avoid side-effects you need to make the Observable shared by using the shareReplay(1) operator and re-use the Observable on your template:

// your component code

ngOnInit() {
  this.dataSource$ = this.service.apiCall().pipe(
    shareReplay(1)
  )
}
<!-- On your HTML template -->
<div *ngIf="dataSource$ | async as data">{{data |json }}</div>
<div *ngIf="dataSource$ | async as data">{{data |json }}</div>

Even though there are technically two subscriptions in this snippet, since we made the Observable shared you should only see 1 network request, and the result of it should be re-used.

If you perform this.service.apiCall() many times, then every time you're creating a new Observable that is not related what-so-ever with the others and there's no way the Observable is going to be shared

You can read more about sharing Observables and avoiding side-effects here

I had a situation where I had a dropdown in the UI of my angular app that called a function on the component every time I change the dropdown. The function I called subscribed to an observable that got application state. Inside the .subscribe, I had an if statement that called 1 of 4 functions that made api calls, each of which that had their own .subscribe. Each dropdown selection created another subscription, and if I changed the dropdown 3 time, and made a subsequent call to one of those 4 endpoints, it would call it 3 times. 4 changes, 4 time and so on.

My issue was that I didn't unsubscribe to the outer subscription that got the application state that was attached to the function of the dropdown that called one of the 4 endpoint in the if. Any other endpoint I called executed once, but it always executed the last called of those 4 endpoints the number of times of subscriptions that were open.

So unsubscribing from that outer subscription solved my issue. Hope this helps someone.

Related