3

I have a couple of questions about Angular. I recently started to experiment with Angular and really cant get a grip of when I should unsubscribe, there is obviously recommended to use the AsyncPipe but in some cases there is no way to use it.

  • If I subscribe to a HTTP request in a service, does the Observable unsubscribe itself or is it persistent through out the application lifetime?

  • When I subscribe (without the AsyncPipe) to a HTTP request in a component I could manually unsubscribe in the ngOnDestroy lifecycle hook which is fine but in my case I have a submit method to create account

account.component.html

<account-item>
 *ngFor="let account of collection$"
 [data]="account"
</account-item>

account.component.ts

public collection$: Observable<Account[]>;
private subscription: Subscription;

 constructor(
  private service: AccountService
 ) {}

 ngOnInit() {
   this.collection$ = this.service.getAll()
 }

 createAccount(obj) {
  this.subscription = this.service.create(obj)
   .subscribe(
    success => this.collection$ = this.service.getAll(),
    error => Observable.throw(error)
  );
}

ngOnDestroy() {
 this.subscription.unsubscribe();
}

From what I know the subscription is now persistent until my AccountComponent is destroyed, but is there a way to use AsyncPipe here instead or is it better for me to subscribe in the service itself?

I've read something about finite and infinite Observables but haven't really understand when a Observable is finite or not.

  • Another problem I'm facing is that in success => this.collection$ = this.service.getAll() my UI doesn't update with the new account list when I use ChangeDetectionStrategy.OnPush but works just fine with ChangeDetectionStrategy.Default

This is the service method that fetches the account data

 getAll() {
  return this.http.get(ENDPOINT_ACCOUNT)
    .map((response: Response) => response.json().data)
}
  • 6
    Possible duplicate of [Angular2/RxJs When should I unsubscribe from \`Subscription\`](http://stackoverflow.com/questions/38008334/angular2-rxjs-when-should-i-unsubscribe-from-subscription) – eko Mar 30 '17 at 12:52
  • dont worry about unsubscribing http requests -> those are finite, because you make one request, and return data, and thats it. Infinite subscription would be for example subscription to user input. Also you don't have to provide error function -> you can simply remove this line. – charlie_pl Mar 30 '17 at 12:58
  • 1
    @echonax Oh yeah haven't seen that one, looks like it gives a good explanation of the finite and infinite part of my question. – Robin Zetterström Mar 30 '17 at 13:02
  • @charlie_pl so if I would like to subscribe to my http request, Angular will take care of the subscription and whats left of it after I got the response? – Robin Zetterström Mar 30 '17 at 13:42

1 Answers1

1

What you need to think when dealing with Observables and functionnal programming more globaly is that you don't describe how things are done but describe what things are.

In your example, you collection is the combination of on the one hand the initial fetch from the service and on the other hand, all updates that may occur, so if you want to avoid subscribing in the component, you can do such a thing:

class Foo {
  public collection$: Observable < Account[] > ;
  private createAccount$ = new Subject<Account>();

  constructor(
    private service: AccountService
  ) {}

  ngOnInit() {
    let initialAccounts = this.service.getAll().share();
    let accountUpdate = initialAccounts.switchMap(()=>this.createAccount$.switchMap(account=>{
      return this.service.create(account).switchMap(()=>this.service.getAll())
    }))
    this.collection$ = Observable.merge(initialAccounts,accountUpdate);
  }

  createAccount(obj:Account) {
    this.createAccount$.next(obj);
  }

}

We are using here the merge operator to take the data from either initialAccounts or createAccount$. It is always a good thing to combine your observables together and subscribe once, because this way you don't have to imperatively manage your subscription.

The fact is most of the time, you don't need to subscribe() at all.

n00dl3
  • 21,213
  • 7
  • 66
  • 76