How can I make sure all my observables have completed before showing a toast message?

http response interceptor angular 8
intercept http response angular
angular 6 http interceptor error handling
angular http event to httpresponse
angular interceptor
angular 8 http interceptor error handling
angular http interceptor response headers
httpinterceptor in angular 8

I have a scenario in which I have to make some api calls, then show some toast messages informing the user if the calls succeeded or failed. In the code below, the processSaveResponses method gets called before the observable's are resolved. The processSaveResponses method is responsible for displaying the toast messages. I understand this is expected behavior, since observable's are asynchronous, but I don't know how to "wait" unit the observable's have finished.

The deliveryPreferencesService.save and deliveryPreferencesService.saveAutoEnroll methods are independent of each other, but deliveryPreferencesService.saveAutoEnroll should not be called if deliveryPreferencesService.save failed.

  private saveChanges(changeSet: DeliveryPreferencesChangeSet) {

    let deliveryPrefernceResult;
    let saveAutoEnroll = true;

    const { accountPreferences: accountPreferenceChanges, autoEnrollPreferences: autoEnrollPreferenceChanges } = changeSet.changes;

    if (accountPreferenceChanges.length) {
      this.deliveryPreferencesService.save(accountPreferenceChanges).
        subscribe(
          () => deliveryPrefernceResult = true,
          () => saveAutoEnroll = false);
    }

    if (autoEnrollPreferenceChanges.length) {
      if (saveAutoEnroll) {
        this.deliveryPreferencesService.saveAutoEnroll(autoEnrollPreferenceChanges).
          subscribe(
            () => console.log('save auto enroll completed'),
            () => saveAutoEnroll = false);
      }
    }

    this.processSaveResponses([{ success: deliveryPrefernceResult }, {success: saveAutoEnroll}]);
  }

Here is the code for the processSaveResponses :

    if (every(responses, ['success', false])) {
      this.showErrorToastr(this.ALL_CHANGES_FAILURE_MESSAGE);
    }
    else if (every(responses, ['success', true])) {
      this.originalPreferences = cloneDeep(this.currentPreferences);
      this.onChange.next();
      this.showSuccessToastr(this.ALL_CHANGES_SUCCESS_MESSAGE);
    }
    else {
      if ((responses[0] as any).success) {
        this.originalPreferences.accountPreferenceSets = cloneDeep(this.currentPreferences.accountPreferenceSets);
        this.showSuccessToastr(this.DELIVERY_PREFERENCES_SUCCESS_MESSAGE);
        this.showErrorToastr(this.AUTO_ENROLL_FAILURE_MESSAGE);
      } else {
        this.originalPreferences.autoEnrollPreferences = cloneDeep(this.currentPreferences.autoEnrollPreferences);
        this.showSuccessToastr(this.AUTO_ENROLL_SUCCESS_MESSAGE);
        this.showErrorToastr(this.DELIVERY_PREFERENCES_FAILURE_MESSAGE);
      }
    }
  }

Any help would be appreciated. I am using rxjs version 5.5.2.

Try to use switchMap as described here. I guess it can be used in your case. https://www.learnrxjs.io/operators/transformation/switchmap.html

this.deliveryPreferencesService.save(accountPreferenceChanges)
  .pipe(
    switchMap(x => this.deliveryPreferencesService.saveAutoEnroll(autoEnrollPreferenceChanges))
  )
  .subscribe(() => {
    // TODO something
  })

In this case this.deliveryPreferencesService.saveAutoEnroll(autoEnrollPreferenceChanges) will be called only after succeeded this.deliveryPreferencesService.save(accountPreferenceChanges)

Convert Angularfire2/Firestore observable to promise, How can I make sure all my observables have completed before showing a toast message? - angular. How to clear toasts before showing a new toast? #149. I am trying to clear all the previous toastr message before I call this again. How can I do that?

You need to use the zip

import { of, zip } from 'rxjs';



const x1$ = of('Hello');
const x2$ = of('World!');
const x3$ = of('Goodbye');
const x4$ = of('World!');

const subscription = zip(x1$, x2$, x3$, x4$).subscribe( res => {
  console.log(res);
});

["Hello", "World!", "Goodbye", "World!"]

OK 👍

Angular 8 timeout, How can I make sure all my observables have completed before showing a toast message? I have a scenario in which I have to make some api calls, then show� I want to remove the toast message conditionally from Action Center , when user login again. To my knowledge, this can be achieved by assigning tag to the toast message. Later toast message can be removed from Action Center using PowerShell by referring the tag, but I do not know the PowerShell code to use. Thanks, Thangaselvam. Reply

Sorry, I've got. You can do it by using async\await with promises. Now it should work by your scenario.

  private async saveChanges(changeSet: DeliveryPreferencesChangeSet) {
    const { accountPreferences: accountPreferenceChanges, autoEnrollPreferences: autoEnrollPreferenceChanges } = changeSet.changes;

    if (accountPreferenceChanges.length) {
      await this.deliveryPreferencesService.save(accountPreferenceChanges).toPromise();
    }

    if (autoEnrollPreferenceChanges.length) {

        await this.deliveryPreferencesService.saveAutoEnroll(autoEnrollPreferenceChanges).toPromise();
    }

    this.processSaveResponses([{ success: true }, {success: true}]);
  }

More about async/await in TS https://tutorialedge.net/typescript/async-await-in-typescript-tutorial/

Handle http responses with HttpInterceptor and Toastr in Angular , The following picture will show you what we were doing so far for AngularJS To create a new project, install the angular-cli if you haven't done so already used to implement the alert / toaster notification example in Angular 8, you don't need Delays the emission of items from the source Observable by a given timeout� Weave humor into your toast, but don't embarrass the honoree. If the assembled group is close-knit, it's all right to refer to shared experiences, but don't make the toast a private joke between you and a few of the people present. When you have finished your toast, lift your glass to the recipient and lead the group in drinking to that person.

onTap Event � Issue #273 � scttcper/ngx-toastr � GitHub, I am sure that every time you work in a big project with a ton of http requests, an http interceptor and the ngx-toastr plugin to display those messages. can be implemented by a class and it has only one method that intercepts an req (a HttpRequest ) and next (a HttpHandler ) and returns an Observable Employees aren’t thinking about how much an extra 15 minutes on the clock will cost you. When you integrate HotSchedules with your Toast POS system we’ll make sure they clock in and out within a threshold. Powered by Froala Editor. Powered by Froala Editor

Toasts overview, I would like to have a link in my Toast so that the user can follow up on I can use the onTap observable if the click Event is passed through This is how Android, IOS, browsers, etc all display their toasts/notifications for the most part. like we should be completing it when the toastr is completed which is� Toast and OpenTable GuestCenter integrate to provide restaurants with deeper spend insights into their guests, enable better hospitality and improve operational efficiencies.

Angular pitfall: Multiple HTTP requests with RxJS and observable , Overview � Get started � Layouts and binding expressions � Work with observable data You can display the toast notification with show() , as shown in the This example demonstrates everything you need for most toast If a simple text message isn't enough, you can create a customized layout for your� But where live data comes in, the current Resolve behavior is difficult to make use of. If we suppose the live data stream never completes, we have to instead resolve, for example, to Observable.first(), and throw away the remainder of the stream. Or I can go through extra steps for each of my Observables, to Observable.publish etc.

Comments
  • you can change observable to promise and then wait for the response. and then complete your calls.
  • This is very close to what I need, but this.deliveryPreferencesService.saveAutoEnroll can be called without this.deliveryPreferencesService.save.
  • No, this.deliveryPreferencesService.saveAutoEnroll will be called only after calling deliveryPreferencesService.save(accountPreferenceChanges). If deliveryPreferencesService.save(accountPreferenceChanges) is not called, deliveryPreferencesService.save(accountPreferenceChanges) won't be called.
  • They will be called strictly consistently
  • What I meant in my previous comment was in my scenario, the this.deliveryPreferencesService.saveAutoEnroll can be called alone IF autoEnrollPreferenceChanges.length is greater than zero AND accountPreferenceChanges.length is equal to zero.
  • @broke, you could start with an iif , like iif(condition, save(), of(undefined)) and then switchMap to saveAutoEnroll
  • Not sure how this would help. I don't want to call saveAutoEnroll if deliveryPreferencesService.save failed