Search code examples
javascriptreact-nativetreeview

Constructing Tree View Object


I'd like to construct an Array Object for tree view in React Native.

Realm DB returns following rows as they have parent-child relation:

{
   "0":{
      "ID":3,
      "name":"KITCHEN",
      "parentID":2,
      "createdBY":null,
      "createdAT":null
   },
   "1":{
      "ID":4,
      "name":"BATHROOM",
      "parentID":2,
      "createdBY":null,
      "createdAT":null
   },
   "2":{
      "ID":5,
      "name":"OIL",
      "parentID":3,
      "createdBY":null,
      "createdAT":null
   },
   "3":{
      "ID":6,
      "name":"LIQUID",
      "parentID":5,
      "createdBY":null,
      "createdAT":null
   },
   "4":{
      "ID":7,
      "name":"SOLID",
      "parentID":5,
      "createdBY":null,
      "createdAT":null
   }
}

Object should be look like this:

 const treeData = [
      {
        key: 3,
        label: 'KITCHEN',
        nodes: [
          {
            key: '5',
            label: 'OIL',
            nodes: [
              {
                key: '6',
                label: 'LIQUID',
              },
              {
                key: '7',
                label: 'SOLID',
              },
            ],
          },
        ],
      },
      {
        key: 4,
        label: 'BATHROOM',
      },
    ];

My attempt was looping over all rows and get their IDs then in a nested loop checking the parentID with the ID and if any match occurs then adding that node to another object.

This only gives me the child/s of any parent.

for (var i = 0; i < rows.length; i++) {
      let tempID = rows[i].ID
      treeData = treeData.concat(rows[i])
      for (var j = 0; j < rows.length; j++) {
        let tempParentID = rows[j].parentID
        if (tempID == tempParentID) {
          subCategoryJson = subCategoryJson.concat(rows[j])
        }
      }
    }

Problem is I am really not sure how to construct exactly the above Array Object.

PS. I'm trying to use following node module: https://www.npmjs.com/package/react-simple-tree-menu


Solution

  • You could store the keys and filter the parentt nodes for the result.

    var data = { 0: { ID: 3, name: "KITCHEN", parentID: 2, createdBY: null, createdAT: null }, 1: { ID: 4, name: "BATHROOM", parentID: 2, createdBY: null, createdAT: null }, 2: { ID: 5, name: "OIL", parentID: 3, createdBY: null, createdAT: null }, 3: { ID: 6, name: "LIQUID", parentID: 5, createdBY: null, createdAT: null }, 4: { ID: 7, name: "SOLID", parentID: 5, createdBY: null, createdAT: null } },
        tree = function (data) {
            var t = {},
                parents = {};
    
            Object.values(data).forEach(({ ID: key, name: label, parentID }) => {
                Object.assign(t[key] = t[key] || {}, { key, label });
                t[parentID] = t[parentID] || { };
                t[parentID].nodes = t[parentID].nodes || [];
                t[parentID].nodes.push(t[key]);
                parents[key] = true;
            });
            return Object
                .keys(t)
                .filter(k => !parents[k])
                .flatMap(k => t[k].nodes);
        }(data);
    
    console.log(tree);
    .as-console-wrapper { max-height: 100% !important; top: 0; }