0

I got some tree object data from server and I need to transform it to Tree Object for antd design Tree. I can't figure out it solution, so any help would be appreciated.

Given Input

const dataTree = {
  tree: {
    SUBVERSIF: {
      parent: null,
      children: {
        RA: {
          name: "RA - Ragam Anak",
          children: {
            "02": {
              name: "RA.02 - Sinetron Jadul",
              children: {
                "03": {
                  name: "RA.02.03 - Kosong tiga",
                },
              },
            },
          },
        },

        "ARSIP-A": {
          name: "ARSIP-A - Arsip A",
          children: {
            10: {
              name: "ARSIP-A.10 - 2010",
              children: {
                "002": {
                  name: "ARSIP-A.10.002 - 002",
                },
              },
            },
          },
        },
      },
    },
    FASILITATIF: {
      parent: "FASILITATIF",
      children: {
        BN: {
          name: "BN - Contoh",
          children: {
            "03": {
              name: "BN.03 - inventore rem et",
              children: {
                "02": {
                  name: "BN.03.02 - 02",
                },
              },
            },
          },
        },
      },
    },
    SUBSTANTIF: {
      parent: "SUBSTANTIF",
      children: {
        BN: {
          name: "BN - Contoh",
          children: {
            "03": {
              name: "BN.03 - inventore rem et",
              children: {
                "01": {
                  name: "BN.03.01 - XTC",
                },
              },
            },
          },
        },
      },
    },
  },
};

As you can see, there is tree node data that maybe have unknown deeply children from one or some object. Now, I want to transform it to Antd Design Tree that have data defined by TreeNode[]

For the parent / root, they don't have a name field, so the title is retrieved from parent field, and the key field is retrieved from unique key from the tree object, and so on.

Expected Output

const treeData: DataNode[] = [
  {
    title: "SUBVERSIF",
    key: "SUBVERSIF",
    children: [
      {
        title: "RA - Ragam Anak",
        key: "RA",
        children: [
          {
            title: "RA.02 - Sinetron Jadul",
            key: "02",
            children: [
              {
                title: "RA.02.03 - Kosong tiga",
                key: "03",
                isLeaf: true,
              },
            ],
          },
        ],
      },
      {
        title: "ARSIP-A - Arsip A",
        key: "ARSIP-A",
        children: [
          {
            title: "ARSIP-A.10 - 2010",
            key: "10",
            isLeaf: true,
          },
        ],
      },
    ],
    title: "FASILITATIF",
    key: "FASILITATIF",
    children: [
      {
        title: "BN - Contoh",
        key: "BN",
        children: [
          {
            title: "BN.03 - inventore rem et",
            key: "03",
            children: [
              {
                title: "BN.03.02 - 02",
                key: "02",
                isLeaf: true,
              },
            ],
          },
        ],
      },
    ],
    title: "SUBSTANTIF",
    key: "SUBSTANTIF",
    children: [
      {
        title: "BN - Contoh",
        key: "BN",
        children: [
          {
            title: "BN.03 - inventore rem et",
            key: "03",
            children: [
              {
                title: "BN.03.01 - XTC",
                key: "01",
                isLeaf: true,
              },
            ],
          },
        ],
      },
    ],
  },
];

I'm very struggled with object manipulation, i was tried with some method for looping and checking data, but i can't deep down to my last children and can't move to other sibling data

1 Answer 1

1

Here is a recursive function you could use. It takes the tree object (not the top-level object) as argument and maps its entries to an array of TreeNodes. When there is a children property in the source data, the function is called recursively to determine the value of the target's children property:

const convert = (tree) =>
    Object.entries(tree).map(([key, {name, children}]) => ({
        title: name ?? key,
        key,
        ...children && { children: convert(children) },
        ...!children && { isLeaf: true }
    }));

// Demo with example from question:
const dataTree = {tree: {SUBVERSIF: {parent: null,children: {RA: {name: "RA - Ragam Anak",children: {"02": {name: "RA.02 - Sinetron Jadul",children: {"03": {name: "RA.02.03 - Kosong tiga",},},},},},"ARSIP-A": {name: "ARSIP-A - Arsip A",children: {10: {name: "ARSIP-A.10 - 2010",children: {"002": {name: "ARSIP-A.10.002 - 002",},},},},},},},FASILITATIF: {parent: "FASILITATIF",children: {BN: {name: "BN - Contoh",children: {"03": {name: "BN.03 - inventore rem et",children: {"02": {name: "BN.03.02 - 02",},},},},},},},SUBSTANTIF: {parent: "SUBSTANTIF",children: {BN: {name: "BN - Contoh",children: {"03": {name: "BN.03 - inventore rem et",children: {"01": {name: "BN.03.01 - XTC",},},},},},},},},};
const treeData = convert(dataTree.tree);
console.log(treeData);

Sign up to request clarification or add additional context in comments.

2 Comments

It's a great answer, i'm just done this just one hour ago but with so long syntax. I couldn't imagine if the solution can be like what you did, thank you trincot, your answer is very helpful!
That's a beautiful implementation. And TIL that the parentheses I would use in, say, ...(!children && {isLeaf: true}) are not necessary. I'll probably still use them, but it's interesting to realize.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.