0
votes

I want some data to be centrally loaded in the app through a single HTTP request and want this data to be passed on to multiple individual components. I am using the BehaviourSubject class to set the data loaded into an observable object in a shared service and am subscribing to it in individual components.

SharedService:

  data: Observable<any>;

  load_data(){
  this.http.post('/myAPIMethod', {myInputs}).subscribe(
      res => {
              var dataSource=new BehaviorSubject(res);
              this.data = dataSource.asObservable();
          }, error => {
          console.log(error);
      });
  }

app.component.ts:

constructor(private shared: SharedService) { }
ngOnInit(){
  this.shared.load_data();
  }

myComponent.component.ts

constructor(private shared: SharedService) { }
ngAfterViewInit(){
  this.shared.data.subscribe(
      res => {console.log(res)},
      err => {console.log(err)}
    );
}

Since my app.component.ts and myComponent.component.ts files are loading asynchronously and independently, I am getting an error when it tries to subscribe to the 'data' Observable in myComponent even before the app has loaded the data. I get a subscribed of undefined error ('data' is undefined and it is already trying to subscribe).

How do I check for the 'data' Observable value being set before subscribing to it in the myComponent file?

1

1 Answers

1
votes

Use Subject instead:

data = new Subject();

load_data(){
  this.http.post('/myAPIMethod', {myInputs}).subscribe(
      res => {
              this.data.next(res);
          }, error => {
          console.log(error);
      });
}

This way your components can subscribe to the Subject before the data is return, and it emit the data when the http call received.

Additionally, if are you not going to manipulate the DOM / View elements in your subscribe function then call it inside ngOnInit instead: yourComponet.ts

ngOnInit(){
  this.shared.data.subscribe(
      res => {console.log(res)},
      err => {console.log(err)}
    );