Search code examples
angularionic-framework

Issues with BehaviorSubject : Second component receives null after updating state


I’m working with a service in Angular that uses BehaviorSubject to share a Business object between two components. The first component updates the value correctly, but the second component always prints null when subscribing to the BehaviorSubject.

Service Code:

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import { Business } from '../_models/business';

@Injectable({
  providedIn: 'root',
})
export class SharedBusinessStateService {
  private businessSubject = new BehaviorSubject<Business | null>(null);
  business$ = this.businessSubject.asObservable();

  constructor() {}

  updateBusiness(business: Business) {
    this.businessSubject.next(business);
    this.logCurrentState();
  }

  logCurrentState() {
    console.log("From Service: " + JSON.stringify(this.businessSubject.value));
  }
}

First Component Code:

onSubmit(formData: any) {
  let business = new Business();
  business.owner = this.businessOwner()!;
  this.sharedBusinessState.updateBusiness(business);
}

Second Component Code:

ngOnInit() {
  this.sharedBusinessState.business$.subscribe((data) => {
    console.log("Business Data in Component: " + JSON.stringify(data));
  });

  // Method to check the current state
  this.sharedBusinessState.logCurrentState();
}

logCurrentState(){
 this.sharedBusinessState.logCurrentState();
}

Behavior: When I call the updateBusiness method from the first component, I can see that the state updates correctly in the service. However, in the second component, the subscription to business$ always prints null. I’ve tried calling the logCurrentState() method from a button in the interface, but it also prints null.

Question: Why does the second component always receive null when subscribing to business$, even though the first component updates the value correctly? Is there something I should check to ensure both components are using the same service instance and receiving the updated value?


Solution

  • Check if you have added SharedBusinessStateService to any providers array, in your application, if you have added the service will have a new instance created and these new instances do not know of emissions from other services.


    Second Component, the log function log should be placed, inside the subscribe, because code inside the subscribe is asynchronous code and the code outside it is synchronous, javascript first executes synchronous code then the async code.

    ngOnInit() {
      this.sharedBusinessState.business$.subscribe((data) => {
        console.log("Business Data in Component: " + JSON.stringify(data));
        // Method to check the current state
        this.sharedBusinessState.logCurrentState();  // <- changed here!
      });    
    }
    
    logCurrentState(){
     this.sharedBusinessState.logCurrentState();
    }