Search code examples
javascriptjsondata-transform

Add a unique key to every parent and children


I just transformed my API called data to a certain format in order to fit into ant design table tree data.

https://ant.design/components/table/#components-table-demo-tree-data

However, now i face another problem.

I need to add a "key" to every parent and children so that the tree data table will render properly. Or else when i try to expand and collapse the tree table, it will cause multiple rows to be created each time I do so.(**Note: as long as the key is unique in every parent and children, it will be fine.)

Would appreciate it a lot if someone can guide me on how I can add a key to both the parent and children.

Bonus if someone is able to help me simplify this long lengthy code. As I feel this may not the best approach for this.

Example below on what i need.

Current Code for data transforming:

//api called data
let apiData = [
  {
    email: "[email protected]",
    permissionIds: null,
    roleIds: ["raa", "baa", "caa"],
    projectIds: ["1aa", "3aa"]
  },
  {
    email: "[email protected]",
    permissionIds: null,
    roleIds: ["baa", "caa"],
    projectIds: ["1aa", "2aa", "3aa"]
  },
  {
    email: "[email protected]",
    permissionIds: null,
    roleIds: ["caa"],
    projectIds: ["1aa"]
  }
];

//isolate and transform data
const data = apiData.reduce((arr, item) => {
    console.log("~~~arr",JSON.stringify(arr));
    console.log("~~~item",JSON.stringify(item));
  let formatted = item.projectIds.map((id) => {
    return {
      projectIds: id,
      children: [{ ...item, projectIds: id }]
    };
  });
  console.log("~~~formatted",JSON.stringify(formatted));
  console.log("arr Formtd", [...arr, ...formatted]);

  return [...arr, ...formatted];
}, []);



//Function to group the data
const findMatch = (arr, projectIds) => 
    arr.find(item => item.projectIds === projectIds)

const grouppingArray = (originalArr) => {
  return Array.isArray(originalArr) ? originalArr.reduce((previousObj, obj) => {
    if (findMatch(previousObj, obj.projectIds)) {
      findMatch(previousObj, obj.projectIds).children.push(...obj.children)
    } else {
      previousObj.push(obj)
    }
    return previousObj
  }, []) : 'Need an array'
}

console.log("FINALLL",JSON.stringify(grouppingArray(data)));


After transforming data:

[
  {
    "projectIds": "1aa",
    "children": [
      {
        "email": "[email protected]",
        "permissionIds": null,
        "roleIds": [
          "raa",
          "baa",
          "caa"
        ],
        "projectIds": "1aa"
      },
      {
        "email": "[email protected]",
        "permissionIds": null,
        "roleIds": [
          "baa",
          "caa"
        ],
        "projectIds": "1aa"
      },
      {
        "email": "[email protected]",
        "permissionIds": null,
        "roleIds": [
          "caa"
        ],
        "projectIds": "1aa"
      }
    ]
  },
  {
    "projectIds": "3aa",
    "children": [
      {
        "email": "[email protected]",
        "permissionIds": null,
        "roleIds": [
          "raa",
          "baa",
          "caa"
        ],
        "projectIds": "3aa"
      },
      {
        "email": "[email protected]",
        "permissionIds": null,
        "roleIds": [
          "baa",
          "caa"
        ],
        "projectIds": "3aa"
      }
    ]
  },
  {
    "projectIds": "2aa",
    "children": [
      {
        "email": "[email protected]",
        "permissionIds": null,
        "roleIds": [
          "baa",
          "caa"
        ],
        "projectIds": "2aa"
      }
    ]
  }
]

Expected result after adding a unique key to each parent and children:

[
  {
    "key": 1,
    "projectIds": "1aa",
    "children": [
      {
        "key": 2,
        "email": "[email protected]",
        "permissionIds": null,
        "roleIds": [
          "raa",
          "baa",
          "caa"
        ],
        "projectIds": "1aa"
      },
      {
        "key": 3,
        "email": "[email protected]",
        "permissionIds": null,
        "roleIds": [
          "baa",
          "caa"
        ],
        "projectIds": "1aa"
      },
      {
        "key": 4,
        "email": "[email protected]",
        "permissionIds": null,
        "roleIds": [
          "caa"
        ],
        "projectIds": "1aa"
      }
    ]
  },
  {
    "key": 5,
    "projectIds": "3aa",
    "children": [
      {
        "key": 6,
        "email": "[email protected]",
        "permissionIds": null,
        "roleIds": [
          "raa",
          "baa",
          "caa"
        ],
        "projectIds": "3aa"
      },
      {
        "key": 7,
        "email": "[email protected]",
        "permissionIds": null,
        "roleIds": [
          "baa",
          "caa"
        ],
        "projectIds": "3aa"
      }
    ]
  },
  {
    "key": 8,
    "projectIds": "2aa",
    "children": [
      {
        "key": 9,
        "email": "[email protected]",
        "permissionIds": null,
        "roleIds": [
          "baa",
          "caa"
        ],
        "projectIds": "2aa"
      }
    ]
  }
]

Solution

  • I'm taking the data after your transformation as the starting point, so the second code block. You could do something like this:

    let key = 1;
    
    transformedData.forEach((item) => {
      item.key = key++;
      item.children.forEach((child) => {
        child.key = key++;
      });
    });