Search code examples
angularrxjsmdc-components

Why do I need to subscribe to my Observable?


I am working on an Angular 8 project using @angular/mdc-web as a wrapper for Material Design. Today I had to fix a bug revolving around an error dialog. The dialog presents an error message and can be closed by clicking an OK button. Pretty straight forward and everything worked as a charm until I got an issue defect reported by the QA guys the day after I implemented it. Apparently, some UI elements (buttons) stopped working after the dialog was closed.

In order to examine the bug, I subscribed to the Observable that was returned by the app's central openDialog function, and suddenly the bug didn't occur anymore. Here is the relevant code of the openDialog function:

const dialogRef: MdcDialogRef<T> = this.dialog.open(
  // irrelevant stuff ommitted
);

return dialogRef.afterClosed().pipe(
  tap(
    () =>
      (this.dialogRefArray = this.dialogRefArray.filter(
        item => item.id !== data.id
      ))
  ),
  delay(500),
  tap(() => this.navigationBlocker.unregister(data.id)),
  map(resultFn)
);

Now, I am rather new to Rxjs, and my question is: Why is afterClosed only called when I have subscribed to it? Like this:

const dialog = this.dialogService.openDialog(
  // irrelevant stuff ommitted
).subscribe(() => {
  dialog.unsubscribe();
});

I don't even need to unsubscribe to make it work. I'm trying to understand how Observables work. I would have suspected that afterClosed is being called when ever the dialog is closed, similar to an event. Why do I have to subscribe to it?

An explanation is greatly appreciated, cheers.


Solution

  • The explanation is really simple. An observable only emit when you subscribe to it.

    Also, even if you don't need to unsubscribe to make it works, it's a good pratice to unsubscribe in order to avoid memory leaks (if it still emit, you will still execute the subscribe callback).