Home > database >  Angular BehaviorSubject always null with .getValue or .subscribe from different routed component
Angular BehaviorSubject always null with .getValue or .subscribe from different routed component

Time:11-02

In my Angular code, I save the JSON object in the service before routing to another page. When the page opens, the service is called to return the BehaviorSubject .getValue() which is always empty. I tried .subscribed but no success. My goal is to save the json object in the service where it can be retrieved by another component.

Here is my 1st component that call the save

my .ts code on the 1st component

constructor(private myService: MyService) { }

onClicktoRouteToAnotherComponent(event: any) {
  this.myService.saveData(this.populatedJSONData); // this has data 

  window.open("http://localhost:4200/myOtherComponent", "_blank");
}

In the service code

private mySubject: BehaviorSubject<
    MyJSONData
> = new BehaviorSubject<MyJSONData>({} as MyJSONData);

public readonly $myJSONData: Observable<MyJSONData> = this.mySubject.asObservable();


saveJSONData(_data: MyJSONData) {
    this.mySubject.next(_data);
}

getJSONData() {
    return this.mySubject.getValue();
}

When the new component is being called, it only goes to the constructor and not the ngOnInit or ngOnChanges

 constructor(myService: MyService) {
      myService.subcribe(data => {
        console.log(data); // always empty
      }
    
      let data = myService.getJSONData(); always empty
    }

In the app.module.ts

providers: [MyService], 

Any help is appreciated. If there is another way to persist object on the service, that would be great. Thanks in advance.

CodePudding user response:

BehaviorSubject only stores the value for the application in the current tab. So the fix depends on what you want to achieve:

  1. If you want to just open the component in same tab and use the value from the service then add routing to your app and navigate by using this.router.navigate('route-to-my-other-component');. You can find more at https://angular.io/guide/routing-overview
  2. If you want to open another tab and access JSON data there then use the localStorage in the browser and read the data in service constructor. More info about localStorage: https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage

CodePudding user response:

When you go

window.open("http://localhost:4200/myOtherComponent", "_blank");

you are opening a new window i.e. equivalent to loading up the page for the first time. It's a new instance of the app running. So this.myService.saveData(this.populatedJSONData); is only affecting the old instance. Angular is a single page application and we navigate via routing e.g. this.route.navigate(['home']) but this all happens on the same page, the same index.html with modules loading as needed in the case of lazy modules.

If you stick a log like below in some singleton service you'll see that the two windows have different time i.e. they have been created separately.

  constructor() {
    console.log("SomeService", new Date().toString())
  }
  • Related