2
votes

This might be a basic question, but didn't found any answer which is sufficient. So that's why I thought creating a SO.

I have a form which has a submit handler.

<form class="form login" [formGroup]="loginForm" (ngSubmit)="onSubmit()" novalidate>

On submitting I call a function which subscribes to an observable, that executes a HTTP call to firebase (using the AngularFire2 library).

public onSubmit() : void {
    const values = this.loginForm.value;

    let subscription = this.loginUsernamePassword(values.email, values.password).subscribe((data) => {
        this.processLogin(data);
    }, (error) => {
        console.log("erreur" + error);
    }, () => {
        console.log("one");
    });
}

Now suppose that I submit the form multiple times, then multiple subscriptions are created. What I'm concerned about is data cleanup (unsubscribe), but don't know what is the best way to handle this, especially because this a one-shot function. I see two solutions.

1) Store the subscription in a collection of subscriptions, which gets destroyed 'ngOnDestroy' when the component is removed. But I think for this situation: a single HTTP call, it's a bit weird.

2) Unsubscribe immediately after the oberservable completed.

3) .. any other?

Thanks for you help and tips.

1
I'd highly recommend you to go over "RxJS: Don’t Unsubscribe" by Ben LeshPankaj Parkar

1 Answers

2
votes

One way of handling long-term subscriptions in a component is to ensure they are disposed by adding a condition to the subscription, like so...

export class MyClass implements OnInit, OnDestroy {
  public isDestroyed = false;
  public someData: Observable<SomeData>;

  public ngOnInit() {
    this.someData = {some other source}
    .takeWhile(!this.isDestroyed)
    .subscribe(x => x...........);
  }

  public ngOnDestroy() {
    this.isDestroyed = true;
  }
}

Although I suspect the parent observable might hold on to this subscription until a next value is passed along and it then discovers the subscriber is no longer interested. It might be better to use takeUntil, because that takes an Observable you could call next on to terminate the subscription immediately.

In your situation though it really depends on what this.loginUsernamePassword does. If it is a subscription based on a http call then the subject created by http will be destroyed anyway, and then your local subscription will disappear with it.