Our REST-API is designed to be frontend agnostic, meaning it always sends the IRI to nested resources. This results in multiple HTTP calls needed to retrieve data; first for the parent resource, then its child resources and so on. Each Country has linked Entries, with each entry connected to a product that has an 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;
}
To construct a navigation tree displaying all required data, 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, being new to Angular and RxJS, I am facing challenges ensuring all asynchronous calls are completed before constructing the navigation tree. The current chaining approach feels inefficient and messy. I'm seeking guidance on refactoring the code using better RxJS methods but unsure where to start, especially when handling nested resource IRIs and creating nodes for tree navigation.
Any assistance on how to refactor this code would be greatly appreciated.