0

I'm using Angular to call an external API. Json data is in format like:

[
      {
        "AccessGroupsIdList": [],
        "FirstName": "Greg",
        "LastName": "Tipton",
        "LocationIdList": [],
        "PermissionProfile": {
          "Name": "Agent",
          "PermissionProfileId": {
            "ID": "xy678219-bd7c-103d-b56b-1f1234a85990"
          },
          "Type": 3
        },
        "ManagerName": "Gilchrist, George",
        "Status": true,
        "UserGroupID": {
          "ID": "00000000-0000-0000-0000-000000000000"
        },
        "UserGroupName": "ROOT",
        "UserId": {
          "ID": "4445cc66-819a-4da0-8fbf-d0bb8ce65941"
        }
      }
    ]

How do I create a class in typescript to read it since json data is nested?

export class Employees
{
    AccessGroupsIdList: string[];
    FirstName: string;
    LastName: string;
    LocationIdList : number[];
    PermissionProfile ??
    ManagerName: string;
    Status: boolean;
    UserGroupID ??
    UserGroupName : string;
    UserId ??
}

Please guide if the PermissionProfile, PermissionProfile will be separate nested classes?

How do I declare those?

Andrew Halil
  • 1,195
  • 15
  • 15
  • 21
SilverFish
  • 1,014
  • 6
  • 28
  • 65

2 Answers2

2

Try declaring the Typescript class structures as follows:

export class Employees
{
    AccessGroupsIdList: string[];
    FirstName: string;
    LastName: string;
    LocationIdList : number[];
    PermissionProfile: PermissionProfile;
    ManagerName: string;
    Status: boolean;
    UserGroupId: UserGroupID;
    UserGroupName : string;
    UserId: UserID;
}

export class PermissionProfile 
{
    name: string;
    permissionProfileId: PermissionProfileID;
    type: string;
}

export class PermissionProfileID
{
    id: string;
}
 
export class UserGroupID
{
    id: string;
}

export class UserID
{
    id: string;
}

I would suggest to name the property names consistently with an Id (e.g. with UserGroupId). The name and type class property names are valid in TypeScript (unlike with the C# syntax).

Andrew Halil
  • 1,195
  • 15
  • 15
  • 21
  • I would personally suggest using `interface` instead of `class` here, but this is generally how people do this sort of thing. It is always possible to type output from an XHR request so that you don't get errors from the TS compiler. – Jhecht Oct 19 '21 at 22:57
  • 1
    i would use interface, plus no need for separate id classes, instead create one generic – Nonik Oct 19 '21 at 23:03
  • Nonik/Jhecht, So if you suggest using an interface, would each of the class be replaced by an interface? Or each nested class here will be interfaces, and the implementing class be regular class? – SilverFish Oct 19 '21 at 23:13
  • If the structure(s) are being instantiated within the application then class declarations for structures can be used, otherwise declare as interface for type checking purposes. It depends on other application requirements later on. – Andrew Halil Oct 19 '21 at 23:27
2

To extend Andrew Halil's answer, I would use interfaces instead of classes in your definitions, since there do not appear to be any class methods involved; you are just describing the shape of a JSON object returned from a server

export interface Employee
{
    AccessGroupsIdList: string[];
    FirstName: string;
    LastName: string;
    LocationIdList : number[];
    PermissionProfile: PermissionProfile;
    ManagerName: string;
    Status: boolean;
    UserGroupId: ID;
    UserGroupName : string;
    UserId: ID;
}

export interface PermissionProfile 
{
    name: string;
    permissionProfileId: ID;
    type: string;
}

export interface ID
{
    id: string;
}
 

Now as for an implementation, I don't use Angular all that much but you would do something like this to get the items typed


async function listEmployees(): Promise<Employee[]> {
// Make a fetch call to the API endpoint
   const data = await fetch('https://some-api-endpoint.web/employees')
      // if the response comes back ok, return the JSON-ified response.
      .then(res => {
          if(res.ok) return res.json()
          return [];
      });
    // Instruct typescript that "data" is to be treated as an array of Employee elements.
    return data as Employee[]
}
Jhecht
  • 4,407
  • 1
  • 26
  • 44