I have a task in which I need to convert an Array of Objects data to specified data tree structure for to display it in frontend tree-table
. This below is my Array of Objects data.
<!-- This is my JSON Data --> Collection: { Fields: [{ fieldName: 'mainField', properties: [{ id: 1, carName: 'carName_01', type:string' }, { id: 2, carName: 'carName_02', type: 'object', ref: 'subField' }] }, { fieldName: 'subField', properties: [{ id: 1, carName: 'carName_11', type: 'string' }, { id: 1, carName: 'carName_12', type: 'object', ref: 'subField1' }] }, { fieldName: 'subField1', properties: [{ id: 1, carName: 'carName_21', type: 'string' }] }] }
I have to change this data into this below following data structure.
<!-- Desired Output --> tableData: [{ id: 1, carName: 'carName_01', type: 'string' }, { id: 2, carName: 'carName_02', type: 'object' source: 'subField' children: [{ id: 11, carName: 'carName_11', type: 'object', ref: 'subField1', children: [{ id: 12, carName: 'carName_12', type: 'string' }] }
I have tried to do this using Recursion in methods but, I can’t do that in a way that I want. My task is I have to add an children whenever the type: 'object'
is object with another referenced object inside that array of objects. And by the way the data is dyanmic which is from mongodb database. That’s just a simplified version of the code.
If my information is not enough or seemed unreasonable sorry for that, I am fresher so, I just asked what i want. Thank you in advance for the help.
Advertisement
Answer
First
First, two notes:
On StackOverflow, we expect you to do your own work, and to present your best attempt, explaining where it went wrong. This is a question-and-answer site, not a code-it-for-you one. I’m going to try to answer you this time, but for the future, please read up on asking good questions.
Your comment “This is my JSON Data” is not accurate. JSON is a string format, used to transfer data between different systems or store it. What you have here is plain JavaScript data structures.
Answer
I think this is a fairly simple solution. But it makes one assumption that may not be justified. I didn’t see any way to distinguish your root objects in your input structure, except that they were first. I chose to use the first model
as the source of your root objects. If you need to choose instead the one that has the model name of "form"
, we could change that easily enough.
The code looks like this:
const convertModels = (models, key) => models .filter (({model}) => model == key) .flatMap ( ({attributes}) => attributes .map (att => ({ ... att, ... (att.type == 'object' ? {children: convertModels (models, att.source)} : {}) })) ) const convert = (dictionary) => ({ tableData: convertModels (dictionary .models, dictionary .models [0] .model) }) const dictionary = {models: [{model: "form", attributes: [{id: 1, name: "field_01", displayName: "Field 01", type: "string"}, {id: 2, name: "field_02", displayName: "Field 02", type: "object", source: "subForm"}]}, {model: "subForm", attributes: [{id: 11, name: "subForm_01", displayName: "Field 01", type: "string"}, {id: 12, name: "subForm_02", displayName: "Field 02", type: "object", source: "dialogForm"}]}, {model: "dialogForm", attributes: [{id: 21, name: "dialogForm_01", displayName: "Field 01", type: "string"}]}]} console .log (convert (dictionary))
.as-console-wrapper {max-height: 100% !important; top: 0}
Our main function is convertModels
, which accepts a list of models and the key we’re going to search for. It searches the models for those one(s) with that key, and then flat-maps their attributes
by copying all properties and, if the type is "object"
, adding a children
node by recurring on the models and the source
field.
We wrap this in convert
which handles your outer object, its models
property convert
along with the first model’s model
property, storing the result in a tableData
property of a new object.
If you did want to use the "form"
identifier instead of using the first record, the code is slightly simpler:
const convertModels = (models, key = 'form') => // only slightly more complex models .filter (({model}) => model == key) .flatMap ( ({attributes}) => attributes .map (att => ({ ... att, ... (att.type == 'object' ? {children: convertModels (models, att.source)} : {}) })) ) const convert = (dictionary) => ({ tableData: convertModels (dictionary .models) // simpler })