it's my first post here ! (so please be nice ^^')
It's been a couple of days that I search for the best way to enrich data from a http backend in Angular. Here's my problem:
I have an http backend which provides me the content of a database. The result can be modelized by theses three interfaces:
interface interfaceA {
id: number,
value1: string,
value2: number
}
interface interfaceB {
id: number,
value3: number,
value4: number
}
interface interfaceAB {
id: number,
interfaceA: interfaceA,
interfaceB: interfaceB
}
interface x {
...
...
}
And I have components which take the interfaces and display it in the UI. For now, the components show only the value of the data from the backend api.
I would like add more data in the interfaces (interfaceA, interfaceB and interfaceAB) to precise how to show the values into the component (with sub components using ng-container and *ngComponentOutlet): show a text? A link? in different color or underlined etc...
It woud be something like this:
interface interfaceA {
{id: number, component:any, componentInput: {}},
{value1: string, component: any, componentInput: {}},
{value2: string, component: any, componentInput: {}}
}
For now I tried to implement some classes which contain the interfaces, the components and the components inputs
abstract class data<T> {
data: T; //InterfaceA, interfaceB, interfaceAB
abstract components: {};
abstract componentsInputs: {}
}
export type interfaceA = {
id: number,
value1: string,
value2: number
}
export var interfaceAComponents = {
id: LinkComponent,
value1: TextCOmponent,
value2: Coloredcomponent
}
export class DataClass extends AngularData<DataType> {
override components = DataComponents;
override componentsInput: { [key: string]: {[key: string]: any} } = {
id: {input: this.data.id, link: "https://randomurl?id=" + this.data.id},
value1: {text: this.data.value1},
value2: {text: this.data.value2, color: red}
}
Which allow us to get data in the component like this:
interface Item {
key: string,
componentInput: any,
component: Type<any>
}
class RandomCOmponent implements OnChange{
@Input() data!: data<any>;
items: Item[];
ngOnChange(): void {
if (!this.data) {
console.log("data is empty: ", this.data);
return;
}
this.items = this.parseItem(this.data);
}
parseItem(data: AngularData<{[key: string]: any}>, dataList: Item[] = [], root: string = '') {
let keys = Object.keys(data.data);
for (let key of keys) {
let value = data.data[key];
let component = data.components[key];
let componentInput = data.componentInput[key];
if (!component) {
component = TextComponent;
}
if (value instanceof Object) {
dataList = this.parseItemBis(value, dataList, root + key + ".");
}else {
dataList.push({
key: root + key,
component: component,
componentInput: componentInput
});
}
}
return dataList;
}
}
<table>
<tr>
<th *ngFor="let column of items">
{{column.key}}
</th>
</tr>
<tr">
<td *ngFor="let column of items">
<ng-container *ngComponentOutlet="column.component; inputs: column.componentInput"/>
</td>
</tr>
</table>
But someone said me using classes to manage static data and is a bad practice and that it is better interfaces.
So, do you think my solution is correct ? what is the best way for you to enrich the data I get from the api ? Knowing I will in the future add new data in these interfaces, or create similar interfaces to match with other tables in my database.
I hope my question is clear, Thanks in advance for your answers :)
To me this is a bit hard to follow, I am not sure what exactly the goal is here. I'll try to answer some of the questions:
interfacesortypesto represent data structure. Otherwise you cannot even specify the type of an object and end up usinganyeverywhere. Which kind of defeats the purpose of TypeScriptngSwitchinstead might be the better option.