Reputation: 5611
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
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