RxJS Observable data when awkward?

I have a couple of questions about Angular. I recently started experimenting with Angular and really can't figure out when I should unsubscribe, obviously it is recommended to use AsyncPipe, but in some cases there is no way to use it.

  • If I subscribe to an HTTP request on a service, does the Observable infer its subscription, or is it persistent throughout the lifetime of the application?

  • When I subscribe (without AsyncPipe) to an HTTP request in a component, I can manually unsubscribe in the ngOnDestroy lifecycle cache, which is good, but in my case I have a submit method to create an 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 now persists until my AccountComponent is destroyed, but is there a way to use AsyncPipe here, or is it better for me to subscribe in the service itself?

I read something about finite and infinite Observables, but didn't really understand when the Observable is finite or not.

  • Another problem I am facing is that success => this.collection$ = this.service.getAll()

    my UI is not updated with the new list of accounts when I use ChangeDetectionStrategy.OnPush

    , but works fine withChangeDetectionStrategy.Default

This is the service method that retrieves the account details

 getAll() {
  return this.http.get(ENDPOINT_ACCOUNT)
    .map((response: Response) => response.json().data)
}

      

+3


source to share


1 answer


What you need to think more globally when working with Observables and functional programming is that you are not describing how things are, but describing what they are.

In your example, the collection is a combination of, on the one hand, an initial fetch from the service, and on the other hand, all the updates that might happen, so if you want to avoid subscribing to a component, you can do this 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);
  }

}

      



Here we use an operator merge

to enter data from initialAccounts

or createAccount$

. It's always good to mix your observables together and subscribe once, because this way you don't necessarily need to manage your subscription.

In most cases, you don't need to subscribe()

at all.

+1


source







All Articles