Search code examples
reactjstreeview

Tree view in React


This is my data:

{
  "studentId": "P1",
  "assignments": [
    {
      "CourseId": 111,
      "subjectId": "",
      "topics": [
        {
          "topicId": "t1",
          "isAssigned": false
        }
      ]
    },
    {
      "CourseId": 112,
      "subjectId": "s1",
      "topics": [
        {
          "topicId": "t1",
          "isAssigned": false
        },
        {
          "topicId": "t2",
          "isAssigned": false
        }
      ]
    },
    {
      "CourseId": 111,
      "subjectId": "",
      "topics": [
        {
          "topicId": "t3",
          "isAssigned": false
        }
      ]
    },
    {
      "CourseId": 113,
      "subjectId": "s2",
      "topics": [
        {
          "topicId": "t4",
          "isAssigned": false
        }
      ]
    },
    {
      "CourseId": 114,
      "subjectId": "",
      "topics": [
        {
          "topicId": "t5",
          "isAssigned": false
        }
      ]
    },
    {
      "CourseId": 115,
      "subjectId": "s4",
      "topics": [
        {
          "topicId": "t6",
          "isAssigned": false
        }
      ]
    }
  ],
  "updatedOn": null,
  "updatedBy": null
}

I'm trying to create a tree view in React out of this. I'm using "react-checkbox-tree". The tree view would be created on the assignments object only as the rest of the data is needed only for save functionality.

I have created the basic architecture since I need this in a modal window. It's working fine with hard coded data but I'm finding it difficult to convert my dataset in the format needed for the tree view. Below is the hard-coded object which is working fine.

const nodes = [{
    value: 'mars',
    label: 'Mars',
    children: [
        { value: 'phobos', label: 'Phobos' },
        { value: 'deimos', label: 'Deimos' },
    ],
}];

Solution

  • Try below code. This is basically converting all first values into object with {value.., label..} If there is any specific condition in your code that it should not consider first object always then do mention it in your question.

        const assignments = [
          {
            "CourseId": 111,
            "subjectId": "",
            "topics": [
              {
                "topicId": "t1",
                "isAssigned": false
              }
            ]
          },
          {
            "CourseId": 112,
            "subjectId": "s1",
            "topics": [
              {
                "topicId": "t1",
                "isAssigned": false
              },
              {
                "topicId": "t2",
                "isAssigned": false
              }
            ]
          },
          {
            "CourseId": 111,
            "subjectId": "",
            "topics": [
              {
                "topicId": "t3",
                "isAssigned": false
              }
            ]
          },
          {
            "CourseId": 113,
            "subjectId": "s2",
            "topics": [
              {
                "topicId": "t4",
                "isAssigned": false
              }
            ]
          },
          {
            "CourseId": 114,
            "subjectId": "",
            "topics": [
              {
                "topicId": "t5",
                "isAssigned": false
              }
            ]
          },
          {
            "CourseId": 115,
            "subjectId": "s4",
            "topics": [
              {
                "topicId": "t6",
                "isAssigned": false
              }
            ]
          }
        ];
    const mapAssignment = (object, key) => ({value: key, label: object[key]});
    
    console.log(assignments.map(ass => {
      let assObj = {...mapAssignment(ass, 'CourseId')};
      if(ass.subjectId) {
        assObj['children'] = mapAssignment(ass, 'subjectId');
        if(ass.topics.length > 0) assObj['children']['children'] = ass.topics.map(child => mapAssignment(child, 'topicId'))
      }
      else if(ass.topics.length > 0) assObj['children'] = ass.topics.map(child => mapAssignment(child, 'topicId'))
      return assObj;
    }));