简体   繁体   中英

How to make a data model in angular/typescript having nested objects

I have getting a json array from a api.

[
    {
        id: 1,
        parentId: null,
        name: 'category 1' 

    },
    {
        id: 2,
        parentId: null,
        name: 'category 2' 

    }
]

so after getting this data i am using this id and call a api to get children.

[
    {
        id: 11,
        parentId: null,
        name: 'category 1 child 1' 

    },
    {
        id: 12,
        parentId: null,
        name: 'category 1 child 2' 

    }
]

further i am these children id to get children.

[
    {
        id: 21,
        parentId: null,
        name: 'child 1 sub child 1' 

    },
    {
        id: 22,
        parentId: null,
        name: 'child 1 sub child 2' 

    }
]

so every child have their own children.final what i want.

[
    {
        id: 1,
        parentId: null,
        name: 'category 1',
        children: [
            {
                id: 11,
                parentId: null,
                name: 'category 1 child 1',
                [
                    {
                        id: 11,
                        parentId: null,
                        name: 'category 1 child 1',
                        children: // further children  

                    },
                    {
                        id: 12,
                        parentId: null,
                        name: 'category 1 child 2',
                        children: // further children

                    }
                ] 

            },
            {
                id: 12,
                parentId: null,
                name: 'category 1 child 2',
                children: // same as above 

            }
        ] 

    },
    {
        id: 2,
        parentId: null,
        name: 'category 2' 

    }
]

what I am trying to achieve this here is my Category and Children Interface and models

export interface ICategory {
  id?: any;
  parentId?: number;
  name?: string;
  children: Children[]
}

export class Category implements ICategory {
  public id?: any;
  public parentId?: number;
  public name?: string;
  public children: Children[]

  constructor(data: ICategory) {
    Object.assign(this, data);
  }
}


export interface IChildren {
  id?: any;
  parentId?: number;
  name?: string;
  children: Children[]
}

export class Children implements IChildren {
  public id?: any;
  public parentId?: number;
  public name?: string;
  public children: Children[]

  constructor(data: IChildren) {
    Object.assign(this, data);
  }
}

Please help me I am new in angular and typescript. Thank you

No need to create multiple interfaces, one interface is enough. I am just giving you the suggestion with type below and you can check the stackblitz try to add more sub childrens

Just type children also as ICategory array -> ICategory[]

export type Category = {
  id: number;
  parentId: null | number;
  name: string;
  children: Category[];
};

@Component({
  selector: "my-app",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"]
})
export class AppComponent {
  name = "Angular " + VERSION.major;

  objs: Category[] = [{
    id: 1,
    parentId: 0,
    name: "parent 1",
    children: [{
      id: 2,
      parentId: 1,
      name: "Child 1",
      children: [{
        id: 3,
        parentId: 2,
        name: "Sub Child 1",
        children: []
      }]
    }]
  }];
}

You only need one interface and in TypeScript we don't use the I prefix like C#/JAVA conventions.

Here is a starter function, it needs to add sub child. I might finish it later but have to go.

export interface Category {
  id?: any;
  parentId?: number;
  name?: string;
  children: Category[]
}

 const first = [ { id: 1, parentId: null, name: 'category 1' }, { id: 2, parentId: null, name: 'category 2' } ]; const second = [ { id: 11, parentId: null, name: 'category 1 child 1' }, { id: 12, parentId: null, name: 'category 1 child 2' } ]; const third = [ { id: 21, parentId: null, name: 'child 1 sub child 1' }, { id: 22, parentId: null, name: 'child 1 sub child 2' } ]; const addChildren = (parent, child) => parent.reduce((results, current) => { const children = child.find(c => c.name.endsWith('child ' + current.id)); results.push({...current, children: children }); return results; }, []); console.log(addChildren(first, addChildren(second, third)));

You can use the library class-transformer . A great package which eases the data model creation.

Example:

import { Type } from 'class-transformer';

export class Employee {
    firstName: string;
    email: string;
    days: string;
    hours: string;

    @Type(() => Availability)
    availablity: Availablity

    constructor(args: Employee) {
      Object.assign(this, args);
    }
}

export class Availability {
    days: string;
    hours: string;

    constructor(args: Availability) {
      Object.assign(this, args);
    }
}

As you can see, with the help of this package, we can use type decorator which allows us to transform nested object. You can check out further here .

Personally, i find it more appropriate way to implement data models then any other ones since it's more properly defined.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM