"In a nutshell: make one HTTP request and pass that data to all components. The issue is that the other components run before I get the response back from the initial HTTP request. All components are just extracting bits of data from the HTTP response object" - Using Angular 4.
Any help would be greatly appreciated, thank you.
Basically, my parent component calls a service that loads my JSON. within the service method, I assign the response from my HTTP request to an Observable using rxjs BehaviorSubject so that I can access and follow from all my components that are subscribed to it. Figured I could just make one call to my server and just grab the parts I want throughout all my components instead of making many calls to the server. Maybe I am going at this all wrong...most likely am.
MY Parent componenet:
constructor(private _service: ProductsService, private data:DataService) {
this.getCatgegories(this.masterProduct);
}
My Service method:
private productCategoriesList = new BehaviorSubject<any>([]);
currentList = this.productCategoriesList.asObservable();
changeCatList(categoriesList){
this.productCategoriesList.next(categoriesList);
}
getCatgegories(masterProduct: number) {
return this.http
.get(this.url)
.map(response => {
let productArray = response.json()[0].products;
let henry = this.getFields(productArray, 'product');
this.changeCatList(henry);
//some parsing of object to get the returned value
return catObj;
});
}
The answer to your first question is you are in right approach. In case you want to notify all the component who ever subscribe to your service is the good way to handle data from server as per your requirement.
This approach will also work where components are not parent child, so it will work for all.
You can also think of @Input
and @Output
if its parent child and emit and event on change and cat catch them in other component. But your approach works good in large number of component.
your approach and correction.
In your service you are exposing 2 observable which can be subscribed. As getCatgegories(masterProduct: number)
is returning an observable you can subscribe to it and get data like below
so change your service to check if data is available then return or else make a call to the service.
// check if the method is called once then directly get the value from `BehavourSubject` or else call the method to get the data.
private productCategoriesList = new BehaviorSubject<any>([]);
currentList = this.productCategoriesList.asObservable();
changeCatList(categoriesList){
this.productCategoriesList.next(categoriesList);
}
getCatgegories(masterProduct: number) {
const availableData = undefined;
this.currentList.subscribe((data) => {
if(data !==[]) { availableData = data; }
});
if(availableData !== undefined ) {
return this.http
.get(this.url)
.map(response => {
let productArray = response.json()[0].products;
let henry = this.getFields(productArray, 'product');
this.changeCatList(henry);
//some parsing of object to get the returned value
return catObj;
});
} else {
return this.currentList;
}
}
Solution to your problem
constructor(private _service: ProductsService, private data:DataService) {
this.ProductsService.getCatgegories(this.masterProduct).subscribe(( data) => {
// do some operation into data
});
}