Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Map an object to another in Typescript

I have a role object that I wanted to map to a TreeNode object using PrimeNG to display it in a tree. The role object is something like this (shown in the picture as well)

role: [
id: ....
name: ....
   description: ....
   roles[]: .....
]

role object

The tree node object has the following structure is:

{
"data": 
[
    {
        "label": "Documents",
        "data": "Documents Folder",
        "expandedIcon": "fa-folder-open",
        "collapsedIcon": "fa-folder",
        "children": [{
                "label": "Work",
                "data": "Work Folder",
                "expandedIcon": "fa-folder-open",
                "collapsedIcon": "fa-folder",
                "children": [{"label": "Expenses.doc", "icon": "fa-file-word-o", "data": "Expenses Document"}, {"label": "Resume.doc", "icon": "fa-file-word-o", "data": "Resume Document"}]
            },
            {
                "label": "Home",
                "data": "Home Folder",
                "expandedIcon": "fa-folder-open",
                "collapsedIcon": "fa-folder",
                "children": [{"label": "Invoices.txt", "icon": "fa-file-word-o", "data": "Invoices for this month"}]
            }]
    },
    {
        "label": "Pictures",
        "data": "Pictures Folder",
        "expandedIcon": "fa-folder-open",
        "collapsedIcon": "fa-folder",
        "children": [
            {"label": "barcelona.jpg", "icon": "fa-file-image-o", "data": "Barcelona Photo"},
            {"label": "logo.jpg", "icon": "fa-file-image-o", "data": "PrimeFaces Logo"},
            {"label": "primeui.png", "icon": "fa-file-image-o", "data": "PrimeUI Logo"}]
    },
    {
        "label": "Movies",
        "data": "Movies Folder",
        "expandedIcon": "fa-folder-open",
        "collapsedIcon": "fa-folder",
        "children": [{
                "label": "Al Pacino",
                "data": "Pacino Movies",
                "children": [{"label": "Scarface", "icon": "fa-file-video-o", "data": "Scarface Movie"}, {"label": "Serpico", "icon": "fa-file-video-o", "data": "Serpico Movie"}]
            },
            {
                "label": "Robert De Niro",
                "data": "De Niro Movies",
                "children": [{"label": "Goodfellas", "icon": "fa-file-video-o", "data": "Goodfellas Movie"}, {"label": "Untouchables", "icon": "fa-file-video-o", "data": "Untouchables Movie"}]
            }]
    }
]

}

 data.roles.forEach((role, index) => {
        //this.roleTree.label = role.Name;
        //this.roleTree.data = role.ID;

        let treeNode: TreeNode = {
            label: role.Name,
            data: role

        }

        this.treeNodes.push(treeNode);
        console.log(role);
        console.log(index);

    });

But this code seems to be too complex when I try 'roles' in 'role' to map to 'children' in treeNode. I have seen some examples like this but it is mapping the same field names.

I'm new to Typesript, is there a workaround to convert my role object with roles to treeNode with children by specifying my fieldname (e.g. name) to be mapped to 'label' of role?

A code example would be highly appreciated.

like image 905
sam Avatar asked Sep 01 '17 00:09

sam


People also ask

How to map an array to another array in typescript?

How to map an array of Objects to another array Objects. 1 Array.map method. This method takes input of n size and convert into new output with same size. ... 2 forEach method in typescript. Declare new result array of any type which are going to assign with part of original array. 3 Lodash and Underscore _.map to populate another array object. ...

How does map function works in typescript?

TypeScript map | How does map function works in TypeScript? map function in TypeScript is used to get the new array from the existing calling array. By using the map function, we can perform any operation on the array elements and create a new array. This newly created array can be with or without the key-value pair.

How to re-map keys in mapped types in typescript?

In TypeScript 4.1 and onwards, you can re-map keys in mapped types with an as clause in a mapped type: type MappedTypeWithNewProperties<Type> = { [Properties in keyof Type as NewKeyType]: Type[Properties]

How to add entries to TypeScript map using set method?

We could initialize the typescript Map with a an array of key-value pairs: var map = new Map ( [ [ "apple", 10 ], [ "banana", 20 ], [ "carraot", 30 ] ]); We can then add entries to typescript map by using the set method: var map = new Map (); map.set ("apple",10); map.set ("banana",20); map.set ("carrot",30);


1 Answers

Well, I'm not 100% sure about the Role and TreeNode types you're using. Here's my guess based on the code in your question.

Role has a few properties you care about, but the tricky one is the roles property, which I am guessing is meant to be an array of Role objects:

interface Role {
  id: string;
  name: string;
  description: string;
  roles: Role[];
}

Likewise, TreeNode has some properties, but the tricky one is the children property which is an array of TreeNode objects. Also, I'm assuming that TreeNode is generic in the type of data, and in this case you want to do TreeNode<Role>, meaning the data property will be a Role object:

interface TreeNode<T> {
  label: string;
  data: T;
  expandedIcon?: string;
  collapsedIcon?: string;
  children: TreeNode<T>[];
}

If those are correct, then you can use the following roleToTreeNode() function to map a Role object to a TreeNode<Role> object:

function roleToTreeNode(role: Role): TreeNode<Role> {
  return {
    label: role.name,
    data: role,
    children: role.roles.map(roleToTreeNode)
  };
}

The children: line is the operative part of the function: you are taking the role.roles array, and mapping each Role element to a TreeNode<Role>, which is what the roleToTreeNode() function does. That is, roleToTreeNode() is a recursive function which calls itself.

Does this make sense? Hope that helps. Good luck!

like image 191
jcalz Avatar answered Nov 12 '22 10:11

jcalz