0

In my angular app we have a process button that makes calls to the backend service to save data changes for an issue and flips a flag for the issue being read.

I'd like to make my HTTP calls synchronous (wait) so I can determine if the data was saved successfully. If the data was saved successfully we'll display a green material snack-bar and success message. If the call(s) fail we'll display a red material snack-bar with error message.

Originally everything was a subscribe which was async. I did the following based on some articles I came across.

const savedFacilityInfo = this.facility.updateFacilityInfo(this.savedFacilityInfo).toPromise();
      savedFacilityInfo.then((data) => {
          this.isFacilityInfoSaved = true;
          console.log(data);
      }).catch((error) => {
        console.log(error);
      })

 const updatedInfo = this.issuesService.updateInfo(this.selectedIssue.issueId, this.savedFacilityInfo).toPromise();
      updatedInfo.then((data) => {
        this.isUpdated = true;
        console.log(data);
      }).catch((error) => {
        console.log(error);
      })
    }

    if(this.isFacilityInfoSaved && this.isUpdated) {
      this.resolvedConfirmation();
    } else {
      console.log("Display Error");
      this.displayErrorConfirmation();
    }

This does run, but it doesn't wait for the two service/http calls to finish before evaluating for the resolved or display confirmation.

Am I missing something or is there a better way to handle this?

lank81
  • 45
  • 6
  • 1
    Does this answer your question? [How do I return the response from an Observable/http/async call in angular?](https://stackoverflow.com/questions/43055706/how-do-i-return-the-response-from-an-observable-http-async-call-in-angular) – R. Richards Jan 12 '22 at 17:38
  • I had tried this before and what happens is I receive a 500 error on the HTTP calls. The regular subscribe or the toPromise calls the HTTP request just fine. Obviously though it doesn't wait for a response before evaluating the IF statement below. Also, it stills goes past my subscribes and evaluates the if statement and goes to the displayErrorConfirmation. – lank81 Jan 12 '22 at 18:21
  • 1
    That doesn't do what you think. The 'then()' and/or 'catch()' blocks will execute asynchronously after the calls complete, the rest of your function will continue immediately and run before you have results. I'd stick with obervables and use the rxjs 'zip' operator so you can subscribe and get both results to process at once. – Jason Goemaat Jan 12 '22 at 18:41
  • Which articles have you been reading that made you come through with this solution? Promises don't work like that. – Leonardo Freire Jan 12 '22 at 18:45

1 Answers1

1

If you need to wait for the two requests, you're better off using forkJoin that will only emit when both Observables complete. If both requests are successful, you'll run the resolvedConfirmation. Otherwise, you'll run displayErrorConfirmation.

forkJoin([
    this.facility.updateFacilityInfo(this.savedFacilityInfo),
    this.issuesService.updateInfo(this.selectedIssue.issueId, this.savedFacilityInfo)
])
.pipe(catchError(err => {
    this.displayErrorConfirmation();
    throw EMPTY; 
}))
.subscribe([answer1, answer2] => {
    this.resolvedConfirmation();
});
Leonardo Freire
  • 269
  • 1
  • 7