Steve Kim
Steve Kim

Reputation: 5611

Angular wait for initial load

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?

Upvotes: 2

Views: 1302

Answers (1)

BeetleJuice
BeetleJuice

Reputation: 40936

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.

Upvotes: 1

Related Questions