0

Angular2, typescript

I have a component that displays 1 object at a time from the server.

On the click of a button, the form does some action on the object, sends data to the server. Immediately in the next line, the next object is got.

this.rawS.updateTags({......}); //Update object
this.candidateC.footerNavigateTo(.....);//Get next object

But there is a race condition where ajax to get next object reaches the server before the updateTags ajax reaches the server.

Code of updateTags is

  updateTags(rawCandidate) {
    this.baseAjaxService.doPost(this.baseUrl + 'tags/update', rawCandidate)
      .subscribe(data => {
        console.log(data);
      });
  }

Code for doPost is

doPost(url, inputParamJSON){
    let httpResponse  = this.http
      .post(url, inputParamJSON, this.options)
      .map(this.extractData)
      .catch(this.handleAjaxError);
    return httpResponse;
}

The route for 'continue_screening' has a route resolver which brings the next object.

How can I ensure that footerNavigateTo() runs only after updateTags has completed its full cycle?

Sonal
  • 321
  • 4
  • 13
  • This is not a race condition. What you're doing is calling `this.candidateC.footerNavigateTo()` before the `this.rawS.updateTags()` callback is invoked. In other words, you're not waiting for the AJAX call to complete before acting on it. @Vincismique's answer is correct, you need to use `flatMap` in order to chain the calls. This answer also might help: https://stackoverflow.com/questions/34104638/how-to-chain-http-calls-in-angular2/34107312 – Daniel T. Feb 17 '17 at 23:19

2 Answers2

2

If what you want is to have different behaviours depending on where the function updateTags(rawCandidate) is called, I propose the following solution:

  updateTags(rawCandidate, action) {
    this.baseAjaxService.doPost(this.baseUrl + 'tags/update', rawCandidate)
      .subscribe(
       data => {
        action(data);

      },
      error => {
          console.log("error"); //handle error here
      });
  }

Then you can call the function like this:

updateTags(rawCandidate, function(data){
   console.log(data);
   this.candidateC.footerNavigateTo(.....);//here you can use data
});
ZanattMan
  • 746
  • 1
  • 7
  • 26
  • The flow is such that updateTags() is used in multiple flows. Cannot have the footerNavigateTo() call in that function. – Sonal Feb 16 '17 at 05:11
  • Then you want a different action depending on where you call updateTags? – ZanattMan Feb 16 '17 at 08:29
1

What you want to achieve here is to chain your two http calls, make them dependents somehow. In Angular 1.X it would be done using promise but with AngularJS 2 you can achieve that using flatMap.

See this link http://www.syntaxsuccess.com/viewarticle/angular-2.0-and-http at Dependent calls section.

PS : As indicated in this post (Combining promises in Angular 2) you can also use toPromise() to transform your Observable (i.e. your async http call) into a Promise, if you are more familiar with it.

Community
  • 1
  • 1