Skip to content
Advertisement

Nodejs how to create a `data tree` with array on result

How to fix or redesign results or create a TreeView after mapping the result using nodejs? this is my code, please check below the desired result

What I want here is that if the QuestionGroupID is existing it will not create another row but it will create array on optionItems

please see the desired result vs current result to understand what i mean

const getquestionnaire = await QuestionnaireModels.getQuestion(yearlevel, section);
const desiredResult = currentResult.map(({ yearlevel, section, Groupname, _id, QuestionDescription, OptionDescription }) => ({
   yearlevel,
   section,
   question: {
      Groupname,
      groupdetails: {
         QuestionGroupID,
         QuestionDescription,
         optionItems: {
            OptionDescription
         }
      }
   }
}))
res.send(getquestionnaire);

getQuestion

async getQuestion(yearlevel, section) {
    let student = await Database.getConnection().models.student;
    let qgroup = await Database.getConnection().models.questiongroups;
    let qdetails = await Database.getConnection().models.questiondetails;
    let oitem = await Database.getConnection().models.optionitems;
    student.hasMany(qgroup, { foreignKey: '_id'});
    student.hasMany(qdetails, {foreignKey: 'QuestionGroupID'});
    let question = await Database.getConnection().models.student.findAll({
     attributes:[
    'yearlevel','section','questiondetails.QuestionGroupID','questiongroups.GroupName','questiondetails.QuestionDescription','optionitems.OptionDescription'
    ],
      where: {
        yearlevel: yearlevel,
        section: section
      },
      include:[
        { model: qgroup, attribute:[] },
        { model: qdetails, attribute:[] },
    ],
      raw: true,
    })
    return result
  },
  let org_data = question.map(async data => {
        let item = await oitem.findAll({
            attributes: ['OptionDescription'],
            where: {QuestionDetailsID: data.QuestionGroupID},
            raw: true
        })
        
        return  item
    })

current result

[
    {
        "yearlevel": "Grade 7",
        "section": "Apple",
        "question":{
            "Groupname": "Third",
            "groupdetail":{
                "QuestionGroupID": 1,
                "QuestionDescription":"Eating Disorder",
                "optionItems":{
                    "OptionDescription": "Test 1"
                }
            }
        }
    },
    {
        "yearlevel": "Grade 7",
        "section": "Orange",
        "question":{
            "Groupname": "Third",
            "groupdetail":{
                "QuestionGroupID": 1,
                "QuestionDescription":"Eating Disorder",
                "optionItems":{
                    "OptionDescription": "Test 2"
                }
            }
        }
    },
    {
        "yearlevel": "Grade 8",
        "section": "Blue",
        "question":{
            "Groupname": "Test Group name",
            "groupdetail":{
                "QuestionGroupID": 2,
                "QuestionDescription":"Test Question",
                "optionItems":{
                    "OptionDescription": "Test"
                }
            }
        }
    }
]

desired result

[
    {
        "yearlevel": "Grade 7",
        "section": "Apple",
        "question":{
            "Groupname": "Third",
            "groupdetail":{
                "QuestionGroupID": 1,
                "QuestionDescription":"Eating Disorder",
                "optionItems":[
                    {
                        "OptionDescription": "Test 1"
                    },
                    {
                        "OptionDescription": "Test 2"
                    }
                ]
            }
        }
    },

    {
        "yearlevel": "Grade 8",
        "section": "Blue",
        "question":{
            "Groupname": "Test Group name",
            "groupdetail":{
                "QuestionGroupID": 2,
                "QuestionDescription":"Test Question",
                "optionItems":{
                    "OptionDescription": "Test"
                }
            }
        }
    }
]

this is related on this Nodejs how to create a `data tree` on result but different problem

dont mind this message dont mind this message dont mind this message dont mind this message dont mind this message dont mind this message dont mind this message dont mind this message dont mind this message

Advertisement

Answer

It’s a simple case of “group array of objects by key using reduce”. After we group by the QuestionGroupID, we take the values of that array and construct for each of grouped arrays the required item with the inner array of optionItems.

var input = [{yearlevel:"Grade 7",section:"Apple",question:{Groupname:"Third",groupdetail:{QuestionGroupID:1,QuestionDescription:"Eating Disorder",optionItems:{OptionDescription:"Test 1"}}}},{yearlevel:"Grade 7",section:"Orange",question:{Groupname:"Third",groupdetail:{QuestionGroupID:1,QuestionDescription:"Eating Disorder",optionItems:{OptionDescription:"Test 2"}}}},{yearlevel:"Grade 8",section:"Blue",question:{Groupname:"Test Group name",groupdetail:{QuestionGroupID:2,QuestionDescription:"Test Question",optionItems:{OptionDescription:"Test"}}}}];

var result = Object.values(input.reduce(function (agg, item) {
  agg[item.question.groupdetail.QuestionGroupID] ??= [];
  agg[item.question.groupdetail.QuestionGroupID].push(item)
  return agg;
}, {})).map(function(arr) {
  var result_item = arr[arr.length-1]
  var optionItems = arr.reduce(function(agg, item) {
    agg.push(item.question.groupdetail.optionItems)
    return agg;
  }, [])
  result_item.question.groupdetail.optionItems = optionItems;
  return result_item;
})

console.log(result)
.as-console-wrapper {
  max-height: 100% !important
}
User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement