we have an REST-API that is frontend agnostic, which means that it always sends the IRI to its nested resources. So to retrieve some data you always have to make multiple http calls (first get the parent resource, then its child resources etc.) So each Country has a list of linked Entries. Each entry is linked to a product, which has a IRI to its category resource.
export interface Country {
countryId: number;
name: string;
code: string;
projects: string[]; //contains an array of IRIs for the project resources
entries: string[];
}
export interface Entry {
entryId: number,
country: string,
information: string,
strategy: string,
action: string,
user: string,
product: string,
salesStatus1: string,
salesStatus2: string,
salesStatus3: string,
salesStatus4: string,
salesStatus5: string,
}
export interface Product {
productId: number,
productName: string,
sharepointId: string,
category: string,
plmId: string,
productStatus1: string,
productStatus2: string,
productStatus3: string,
productStatus4: string,
productStatus5: string,
productComponents: string[]
}
export interface Category {
categoryId: number,
name: string,
children: string[]
}
export class Node {
children: Node[] = [];
name: string;
isProduct: boolean;
}
So to consume all data that i needed to display an navigation tree i wrote the following code :
ngOnInit() {
let nodes: Node[] = new Array<Node>();
this.countriesService.getAll()
.subscribe(
(countries) => {
for (let country of countries) {
let countryNode = new Node();
countryNode.name = country.name;
countryNode.isProduct = false;
for (let entryUrl of country.entries) {
this.entriesService.getByUrl(entryUrl).subscribe(
(entry) => {
this.productsService.getByUrl(entry.product).subscribe(
(product) => {
this.categoryService.getByUrl(product.category).subscribe(
(category) => {
let categoryNode = new Node();
categoryNode.name = category.name;
categoryNode.isProduct = true;
countryNode.children.push(categoryNode);
for (let childrenUrl of category.children) {
this.categoryService.getByUrl(childrenUrl).subscribe(
(childCategory) => {
let categoryChildNode = new Node();
categoryChildNode.name = childCategory.name;
categoryChildNode.isProduct = false;
categoryNode.children.push(categoryChildNode);
}
)
}
}
)
}
)
}
)
}
nodes.push(countryNode);
}
this.dataChange.next(nodes);
}
);
}
However as i am kinda new to Angular and rxjs i am having problems to "wait" until all calls are finished and all data (as its asynchronous) is there (and therefore the navigation tree always misses elements). Also it is kinda ugly and bad practice to chain like this. So i wanted to refactor the code to rxjs-methods, however i am completly lost how to even start with it, because after retrieving data i have to iterate over it again to get the nested resource IRIs and also have to create Node objects for the tree-navigation.
Can you pls give me some help, on how to refactor that code?