2

In my angular project, I have the following setup:

I have API to fetch some data from server at the beginning of the app load:

ItemFetch.ts

At the beginning of app load, it fetches data from API then changes the itemLoaded to true.

import { Http } from '@angular/http';
import 'rxjs/add/operator/map';

...
dataLoaded: boolean = false;

dataAPI(){  //Stores in local storage   
 ...
  .then(data=>{
     this.itemLoaded = true;
  })       
 ...
}

main.ts:

Then, once data is stored, I need to load the stored data only when itemLoaded from ItemFetch.ts is true.

import { dataFromStorage} from './data_from_storage' //local storage

export class main_page {        

constructor(public itemStorage: dataFromStorage){};

ngOnInit(){
   this.fetchInitialData();
}
  //Fetch the data from the storage
  fetchInitialData(){
     this.itemStorage.GetItemDataFromStorage('some_item_id')
      .then((data) => {
          console.log("Got the data!" + data);
      )
  };

}

Question:

How do I share this dataLoaded from one component to another so that I can initiate this.fetchInitialData(); only when dataLoaded is true?

1
  • 1
    I would store the variable in a singleton service. This way both components can inject the service and use it. Commented Aug 12, 2017 at 0:49

1 Answer 1

1

Whenever you find yourself thinking: "I need code to run but only after X happens", you basically need an event handler. In Angular, the easiest way to get that done is with RxJS Observables.

Have a service solely responsible for notifying all interested listeners that the data has arrived.

export class LoadNotifierService{
  public dataLoaded : ReplaySubject<any> = new ReplaySubject();  
}

Provide this service in your AppModule.providers array, and inject the service in the component that loads the data, and in any component that needs to know that loading is complete.

itemFetch: get data, then raise the event

// .next() will cause the ReplaySubject to emit TRUE
loadData().then(e => this.loadNotifier.dataLoaded.next(true));

main: register an event handler to be notified when the data arrives

ngOnInit(){
  // Subscribe will receive notice when the ReplaySubject emits
  // .take(1) guarantees that this will be run only once per ngOnInit()
  this.loadNotifier.dataLoaded.take(1).subscribe(e => this.fetchInitialData())
}

You may need to fix a couple of errors (I didn't run the code), but you get the logic I hope.

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you for the answer. I understand your answer and much appreciated. Just a quick question. What does 'ReplaySubject<any> = new ReplaySubject();' do? Thanks!
It defines dataLoaded as a ReplaySubject type. it's an object that makes it easy to notify listeners when something significant occurs via ReplaySubject.next(). It also makes it easy to listen for those notifications with ReplaySubject.subscribe()
Thanks! Much appreciated! =)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.