mr3k
mr3k

Reputation: 366

Angular subscribe to change of variable in another component

I have an application that consist of 3 components and 1 service:

Desired state:

Current state

  ngOnInit(): void {
    if (this.customerService.customer) {
      this.loadOrders();
    }

    this.customerService.customerObserver.subscribe(customer => {
      if(customer) {
        this.loadOrders();
      }
    });
  }

The functionality worked fine, but I realised that as I do never unsubscribe this messes up the application totally as it creates a lot of subscribes when navigating around. I added unsubscribe in orders (see snippet below), but then when I am navigating around I get the following error: ObjectUnsubscribedErrorImpl {message: 'object unsubscribed', name: 'ObjectUnsubscribedError'}

  ngOnDestroy() {
    this.customerService.customerObserver.unsubscribe();
  }

I have tried to read up on subscribe for a while now but is stuck how to proceed.. Any tips on how to arrange to achieve the desired state?

Upvotes: 0

Views: 3492

Answers (2)

Cristian18
Cristian18

Reputation: 230

You can emit data from the service to the components observers.

private customerSubject = new Subject<number>();
customerSelectedAction$ = this.customerSubject.asObservable();

products$ = this.customerSelectedAction$.pipe(
 switchMap(customerId=>this.http.get<Product[]>(`${this.url}?customerId=${customerId}`))
    .pipe(
      tap(data => console.log(data)),
      catchError(this.handleError)
  ));

orders$ = this.customerSelectedAction$.pipe(
 switchMap(customerId=>this.http.get<Orders[]>(`${this.url}?customerId=${customerId}`))
    .pipe(
      tap(data => console.log(data)),
      catchError(this.handleError)
  ));

selectedCustomerChanged(customer: Customer): void {
  this.customerSubject.next(customer.id);
}

After that, you subscribe to the products$ or orders$ observables depending on which component you are. And use the selectedCustomerChanged(customer: Customer) method from navbar.

Upvotes: 2

Yom B
Yom B

Reputation: 238

You can manage the subscription in each component in a subscription array, you can look here for the best answer: Unsubscribing an array of subscriptions

Another tip, you can use a private BehaviorSubject (and a public asObservable prop), starting with null, so you can remove the customerObserver: Subject<boolean> = new Subject<boolean>(); altogether. You just subscribe to that observable and load orders if the customer is not null (you can also use distinct until changed).

Upvotes: 0

Related Questions