Angular handling multiple the same subscriptions

Issue

I have an angular app with a component that has 2 modal dialogs: the first for confirming the deletion, the second for confirming cancel and I have subscriptions:

this.confirmCancelSubscription = this.interactionService.confirm$.subscribe((confirm: boolean) => {
  console.log(1);
  if (confirm) {
    //some actions
    this.modalRef2.hide();
  }
});

this.confirmDeleteSubscription = this.interactionService.confirm$.subscribe((confirm: boolean) => {
  console.log(2);
  if (confirm) {
    //some actions
    this.modalRef3.hide();
  }
});

Into interaction.service.ts:

private confirmSource = new Subject<boolean>();
confirm$ = this.confirmSource.asObservable();
confirm(confirm: boolean) {
  this.confirmSource.next(confirm);
}

But when I click Delete or Cancel on the modal dialog I see in the browser console 1 and 2.

Is there a way to separate the same subscriptions somehow? Or do I need to create a new method into interaction.service.ts for that?

Solution

You can use filter in pipe. This is an example with pure RxJS

enum DialogType {
  CONFIRM,
  CANCEL,
}

const confirmSource = new Subject<{ type: DialogType; confirm: boolean }>();
const confirm$ = confirmSource.asObservable();
const confirm = (type: DialogType, confirm: boolean) => {
  confirmSource.next({ type, confirm });
};

confirm$
  .pipe(filter((dialog) => dialog.type === DialogType.CANCEL))
  .subscribe((dialog) => {
    console.log('Cancel dialog with', dialog.confirm);
  });

confirm$
  .pipe(filter((dialog) => dialog.type === DialogType.CONFIRM))
  .subscribe((dialog) => {
    console.log('Confirm dialog with', dialog.confirm);
  });

console.log('Confirming true');
confirm(DialogType.CONFIRM, true);

console.log('Confirming false');
confirm(DialogType.CONFIRM, false);

console.log('Canceling false');
confirm(DialogType.CANCEL, false);

console.log('Canceling true');
confirm(DialogType.CANCEL, true);

StackBlitz example

Another option – separate everything

const confirmSource = new Subject<boolean>();
const cancelSource = new Subject<boolean>();
const confirm$ = confirmSource.asObservable();
const cancel$ = cancelSource.asObservable();

const confirm = (confirm: boolean) => {
  confirmSource.next(confirm);
};

const cancel = (confirm: boolean) => {
  cancelSource.next(confirm);
};

cancel$.subscribe((confirm) => {
  console.log('Cancel dialog with', confirm);
});

confirm$.subscribe((confirm) => {
  console.log('Confirm dialog with', confirm);
});

console.log('Confirming true');
confirm(true);

console.log('Confirming false');
confirm(false);

console.log('Canceling false');
cancel(false);

console.log('Canceling true');
cancel(true);

StackBlitz example

Answered By – Bojan Kogoj

Answer Checked By – Dawn Plyler (AngularFixing Volunteer)

Leave a Reply

Your email address will not be published.