Zendog74
Zendog74

Reputation: 75

Recursive JavaScript Function to Build FancyTree JSON

I am trying to build an array of JSON objects for FancyTree (https://github.com/mar10/fancytree/wiki/TutorialLoadData). However, my JSON source (Jira REST service) can have pretty much any structure, so the code to build the array of JSON objects has to be entirely generic and able to handle pretty much anything.

Here is an example of the source JSON:

{
"feed": {
    "entry": [
        {
            "expand": "renderedFields,names,schema,operations,editmeta,changelog,versionedRepresentations",
            "id": "95743",
            "self": "foo.comjira/rest/api/2/issue/95743",
            "key": "XYZ-24600",
            "fields": {
                "MandatoryReviewersInternal": [
                    {
                        "self": "foo.comjira/rest/api/2/customFieldOption/10947",
                        "value": "Test",
                        "id": "10947",
                        "disabled": false
                    }
                ],
                "PlannedDropDate": "2022-02-01",
                "assignee": {
                    "self": "foo.comjira/rest/api/2/user?username=swchambe",
                    "name": "swchambe",
                    "key": "swchambe",
                    "emailAddress": "[email protected]",
                    "displayName": "Sharon W Chamberlain",
                    "active": true,
                    "timeZone": "America/Chicago"
                },
                "ESBEnvironments": {
                    "self": "foo.comjira/rest/api/2/customFieldOption/10120",
                    "value": "All Environments",
                    "id": "10120",
                    "disabled": false
                },
                "RestrictedInformation": "Do not include Proprietary, ITAR or SBU restricted information in this action",
                "subtasks": [
                    {
                        "id": "96160",
                        "key": "XYZ-24601",
                        "self": "foo.comjira/rest/api/2/issue/96160",
                        "fields": {
                            "summary": "Test 1",
                            "status": {
                                "self": "foo.comjira/rest/api/2/status/10338",
                                "description": "",
                                "iconUrl": "foo.comjira/images/icons/statuses/generic.png",
                                "name": "Current",
                                "id": "10338",
                                "statusCategory": {
                                    "self": "foo.comjira/rest/api/2/statuscategory/4",
                                    "id": 4,
                                    "key": "indeterminate",
                                    "colorName": "yellow",
                                    "name": "In Progress"
                                }
                            },
                            "issuetype": {
                                "self": "foo.comjira/rest/api/2/issuetype/10319",
                                "id": "10319",
                                "description": "",
                                "iconUrl": "foo.comjira/secure/viewavatar?size=xsmall&avatarId=11747&avatarType=issuetype",
                                "name": "Affected Document",
                                "subtask": true,
                                "avatarId": 11747
                            }
                        }
                    },
                    {
                        "id": "96466",
                        "key": "XYZ-24614",
                        "self": "foo.comjira/rest/api/2/issue/96466",
                        "fields": {
                            "summary": "Test 2",
                            "status": {
                                "self": "foo.comjira/rest/api/2/status/10338",
                                "description": "",
                                "iconUrl": "foo.comjira/images/icons/statuses/generic.png",
                                "name": "Current",
                                "id": "10338",
                                "statusCategory": {
                                    "self": "foo.comjira/rest/api/2/statuscategory/4",
                                    "id": 4,
                                    "key": "indeterminate",
                                    "colorName": "yellow",
                                    "name": "In Progress"
                                }
                            },
                            "issuetype": {
                                "self": "foo.comjira/rest/api/2/issuetype/10319",
                                "id": "10319",
                                "description": "",
                                "iconUrl": "foo.comjira/secure/viewavatar?size=xsmall&avatarId=11747&avatarType=issuetype",
                                "name": "Affected Document",
                                "subtask": true,
                                "avatarId": 11747
                            }
                        }
                    }
                ],
                "Participants": [
                    {
                        "name": "djcook2(djcook2xyz)"
                    },
                    {
                        "name": "swchambe(swchambexyz)"
                    },
                    {
                        "name": "r_slscdm(JIRAxyz)"
                    }
                ],
                "reporter": {
                    "self": "foo.comjira/rest/api/2/user?username=djcook2",
                    "name": "djcook2",
                    "key": "djcook2",
                    "emailAddress": "[email protected]",
                    "displayName": "Deborah Jane Ott",
                    "active": true,
                    "timeZone": "America/Chicago"
                },
                "CPEOrganization": "xyz",
                "SFSearchandViewLink": "<a href=foo.comportal/web/csa/search?key=95743&projectKey=XYZ&issueType=Change%20Request>S2D-0637</a>",
                "progress": {
                    "progress": 0,
                    "total": 0
                },
                "issuetype": {
                    "self": "foo.comjira/rest/api/2/issuetype/8",
                    "id": "8",
                    "description": "Request for a change to the way the application works.",
                    "iconUrl": "foo.comjira/secure/viewavatar?size=xsmall&avatarId=11737&avatarType=issuetype",
                    "name": "Change Request",
                    "subtask": false,
                    "avatarId": 11737
                },
                "project": {
                    "self": "foo.comjira/rest/api/2/project/13390",
                    "id": "13390",
                    "key": "XYZ",
                    "name": "Configuration Status Accounting",
                    "projectTypeKey": "business"
                },
                "SFIdentifier": "S2D-0637",
                "watches": {
                    "self": "foo.comjira/rest/api/2/issue/XYZ-24600/watchers",
                    "watchCount": 2,
                    "isWatching": true
                },
                "ServerEnvironment": [
                    {
                        "self": "foo.comjira/rest/api/2/customFieldOption/10060",
                        "value": "Production",
                        "id": "10060",
                        "disabled": false
                    }
                ],
                "ScheduleImpact": {
                    "self": "foo.comjira/rest/api/2/customFieldOption/12245",
                    "value": "No",
                    "id": "12245",
                    "disabled": false
                },
                "MissionConfigurationDefinition": [
                    {
                        "self": "foo.comjira/rest/api/2/customFieldOption/12246",
                        "value": "1110-1200",
                        "id": "12246",
                        "disabled": false
                    },
                    {
                        "self": "foo.comjira/rest/api/2/customFieldOption/12247",
                        "value": "1110-2200",
                        "id": "12247",
                        "disabled": false
                    }
                ],
                "updated": "2022-05-23T10:06:45.000-0500",
                "description": "¶ Paragraph\nNonbreaking   Hyphen\nEm Space\nEn Space\n½ One Half Fraction\n¼ One Quarter Fraction\n¾ Three Quarters Fraction\n10⁵ superscript\n6⁵ superscript\nO₂ subscript\n\n± 0177\n≤ 2264\n≥ 2265\n\n10⁰ - 2070\n10¹ - 00B9\n10³ - 00B3\n10² - 00B2\n10⁴ - 2074\n10⁵ - 2075\n10⁶ - 2076\n10⁷ - 2077\n10⁸ - 2078\n10⁹ - 2079\n\nΑ  0391\nΒ  0392\nΓ  0393\nΔ  0394\nΕ  0395",
                "CRStatus": {
                    "self": "foo.comjira/rest/api/2/customFieldOption/10050",
                    "value": "In Work",
                    "id": "10050",
                    "disabled": false
                },
                "summary": "SLS-FSW-SAN-21-0010    SLS FSW Software Authorization Notice (SAN) - PARMD5 Support Tool Release 14.0",
                "SLSPriority": {
                    "self": "foo.comjira/rest/api/2/customFieldOption/10347",
                    "value": "Routine",
                    "id": "10347",
                    "disabled": false
                },
                "TestStatus": [
                    {
                        "self": "foo.comjira/rest/api/2/customFieldOption/10041",
                        "value": "Not Tested",
                        "id": "10041",
                        "disabled": false
                    }
                ],
                "ChangeJustificationRationale": "Looks good to me, but who am I?",
                "CostImpact": {
                    "self": "foo.comjira/rest/api/2/customFieldOption/19251",
                    "value": "No",
                    "id": "19251",
                    "disabled": false
                },
                "ExternalReviewType": {
                    "self": "foo.comjira/rest/api/2/customFieldOption/10370",
                    "value": "Mandatory",
                    "id": "10370",
                    "disabled": false
                },
                "CROffice": {
                    "self": "foo.comjira/rest/api/2/customFieldOption/10342",
                    "value": "SLS",
                    "id": "10342",
                    "disabled": false
                },
                "Rank": "0|i0c9r8:",
                "CrossProgram": {
                    "self": "foo.comjira/rest/api/2/customFieldOption/10294",
                    "value": "No",
                    "id": "10294",
                    "disabled": false
                },
                "Programassignedto": {
                    "self": "foo.comjira/rest/api/2/customFieldOption/10295",
                    "value": "SLS",
                    "id": "10295",
                    "disabled": false
                },
                "Programassignedby": {
                    "self": "foo.comjira/rest/api/2/customFieldOption/10301",
                    "value": "SLS",
                    "id": "10301",
                    "disabled": false
                },
                "ChangeType": [
                    {
                        "self": "foo.comjira/rest/api/2/customFieldOption/10307",
                        "value": "Programmatic",
                        "id": "10307",
                        "disabled": false
                    }
                ],
                "ChangePackageManagerCPM": {
                    "self": "foo.comjira/rest/api/2/user?username=swchambe",
                    "name": "swchambe",
                    "key": "swchambe",
                    "emailAddress": "[email protected]",
                    "displayName": "Sharon W Chamberlain",
                    "active": true,
                    "timeZone": "America/Chicago"
                },
                "ChangePackageManagerAlternateCPMAlternate": {
                    "self": "foo.comjira/rest/api/2/user?username=slcraig",
                    "name": "slcraig",
                    "key": "smclemo2",
                    "emailAddress": "[email protected]",
                    "displayName": "Shanda L Craig",
                    "active": true,
                    "timeZone": "America/Chicago"
                },
                "ChangePackageEngineerCPE": {
                    "self": "foo.comjira/rest/api/2/user?username=cbowab",
                    "name": "cbowab",
                    "key": "cbowab",
                    "emailAddress": "[email protected]",
                    "displayName": "Cheri F Bowab",
                    "active": true,
                    "timeZone": "America/Chicago"
                },
                "status": {
                    "self": "foo.comjira/rest/api/2/status/10631",
                    "description": "",
                    "iconUrl": "foo.comjira/images/icons/statuses/generic.png",
                    "name": "Draft",
                    "id": "10631"
                },
                "Development": "{}",
                "RequestedDate": "2021-05-13",
                "Risk": {
                    "self": "foo.comjira/rest/api/2/customFieldOption/10273",
                    "value": "No",
                    "id": "10273",
                    "disabled": false
                },
                "creator": {
                    "self": "foo.comjira/rest/api/2/user?username=djcook2",
                    "name": "djcook2",
                    "key": "djcook2",
                    "emailAddress": "[email protected]",
                    "displayName": "Deborah Jane Ott",
                    "active": true,
                    "timeZone": "America/Chicago"
                },
                "aggregateprogress": {
                    "progress": 0,
                    "total": 0
                },
                "AssigneeSecurityScan": {
                    "self": "foo.comjira/rest/api/2/user?username=sbattles",
                    "name": "sbattles",
                    "key": "sbattles",
                    "emailAddress": "[email protected]",
                    "displayName": "Sylvia M Battles",
                    "active": true,
                    "timeZone": "America/Chicago"
                },
                "Board": [
                    {
                        "self": "foo.comjira/rest/api/2/customFieldOption/10259",
                        "value": "XYZ",
                        "id": "10259",
                        "disabled": false
                    }
                ],
                "MissionEffectivity": [
                    {
                        "self": "foo.comjira/rest/api/2/customFieldOption/19754",
                        "value": "XYZ",
                        "id": "19754",
                        "disabled": false
                    },
                    {
                        "self": "foo.comjira/rest/api/2/customFieldOption/19756",
                        "value": "AC01",
                        "id": "19756",
                        "disabled": false
                    }
                ],
                "CRNumber": [
                    {
                        "name": "XYZ-0637"
                    }
                ],
                "created": "2021-05-14T15:14:22.000-0500",
                "ASCBBoardDate": "2021-05-18",
                "InitiatorOrganization": "ED10",
                "CPMAssignedDate": "2021-05-14",
                "CRAssignedDate": "2021-05-14",
                "ImpactstoCertifiedData": {
                    "self": "foo.comjira/rest/api/2/customFieldOption/20152",
                    "value": "No",
                    "id": "20152",
                    "disabled": false
                },
                "ASCBReviewSuspenseDate": "2021-05-18",
                "TopLevelLinkTitle": "SV02854 S2D-0637",
                "TopLevelLinkURL": "https://nasa-ice.nasa.gov/Windchill/app/#ptc1/tcomp/infoPage?ContainerOid=OR%3Awt.inf.library.WTLibrary%3A3451955009&oid=OR%3Awt.folder.SubFolder%3A4352888087&u8=1",
                "Initiator": {
                    "self": "foo.comjira/rest/api/2/user?username=kmoorhea",
                    "name": "kmoorhea",
                    "key": "kmoorhea",
                    "emailAddress": "[email protected]",
                    "displayName": "Kathy H Moorhead",
                    "active": true,
                    "timeZone": "America/Chicago"
                }
            }
        }
    ]
}
}

I need to end up with an array of JSON objects that looks like this:

[
{title: "Node 1", key: "1"},
{title: "Folder 2", key: "2", folder: true, children: [
  {title: "Node 2.1", key: "3", myOwnAttr: "abc"},
  {title: "Node 2.2", key: "4"},
  {title: "Folder 3", key: "5", folder: true, children: [
    {title: "Node 3.1", key: "6", myOwnAttr: "xyz"},
    {title: "Node 3.2", key: "7"}
  ]}
]}
]

Here is my current attempt. It is not working as desired.

const createTreeJson = function(){
let treeJson = [];
let treeJsonObj = {};
//loop entry array, but there is only ever 1
feedJson.feed.entry.forEach((entry) => {
    treeJsonObj = {};
    //items
    treeJsonObj.title = "Item";
    treeJsonObj.folder = true;
    let children = [];
    //loop object properties
    Object.entries(entry).forEach(([key, value]) => {
        children.push(createTreeJsonObject(children, key, value));
    });
    treeJsonObj.children = children;
    treeJson.push(treeJsonObj);
});

console.log(treeJson);
}

const createTreeJsonObject = function(children, key, value){
console.log(key, value);
if(value.constructor.name === "Object"){
    //it's an object
    let subChildren = [];
    Object.entries(value).forEach(([key2, value2]) => {
        subChildren.push(createTreeJsonObject(subChildren, key2, value2));
    });
    children.push({
        "title": key,
        "folder": true,
        "children": subChildren
    });
}else if(value.constructor.name === "Array"){
    //it's an array
}else{
    //it's something else
    children.push({
        "key": key,
        "title": `${key}`,
        "tooltip": `${value}`
    });
}

return children;
};

createTreeJson();

Note: feedJson in the code is the above source JSON. I did not want to repeat it again in the code. You can also see it in a Fiddle here: https://jsfiddle.net/ua8vm9p7/1/

I am open to using something like loadash to help with this if it makes it easier. I do have jQuery available too, but am trying to stay away from it.

I can't seem to quite get the logic right. Has anyone done this kind of thing before? Can anyone lend a hand on how I can do it?

Thanks.

Upvotes: 0

Views: 190

Answers (1)

Scott Sauyet
Scott Sauyet

Reputation: 50797

I think simpler code will do this:

const makeFancyMenu = (obj) =>
  Object .entries (obj) .flatMap (([k, v]) =>
    Array .isArray (v)
      ? []
    : Object (v) === v
      ? [{title: k, folder: true, children: makeFancyMenu (v)}]
      : [{key: k, title: `${k}`, tooltip: v}]
  )

const convert = (obj) =>
  obj .feed .entry .map ((o) => ({
    title: 'Item',
    folder: true, 
    children: makeFancyMenu (o)
  }))

const input = {feed: {entry: [{expand: "renderedFields,names,schema,operations,editmeta,changelog,versionedRepresentations", id: "95743", self: "foo.comjira/rest/api/2/issue/95743", key: "XYZ-24600", fields: {MandatoryReviewersInternal: [{self: "foo.comjira/rest/api/2/customFieldOption/10947", value: "Test", id: "10947", disabled: !1}],PlannedDropDate: "2022-02-01", assignee: {self: "foo.comjira/rest/api/2/user?username=swchambe", name: "swchambe", key: "swchambe", emailAddress: "[email protected]", displayName: "Sharon W Chamberlain", active: !0,timeZone: "America/Chicago"},ESBEnvironments: {self: "foo.comjira/rest/api/2/customFieldOption/10120", value: "All Environments", id: "10120", disabled: !1},RestrictedInformation: "Do not include Proprietary, ITAR or SBU restricted information in this action", subtasks: [{id: "96160", key: "XYZ-24601", self: "foo.comjira/rest/api/2/issue/96160", fields: {summary: "Test 1", status: {self: "foo.comjira/rest/api/2/status/10338", description: "", iconUrl: "foo.comjira/images/icons/statuses/generic.png", name: "Current", id: "10338", statusCategory: {self: "foo.comjira/rest/api/2/statuscategory/4", id: 4,key: "indeterminate", colorName: "yellow", name: "In Progress"}},issuetype: {self: "foo.comjira/rest/api/2/issuetype/10319", id: "10319", description: "", iconUrl: "foo.comjira/secure/viewavatar?size=xsmall&avatarId=11747&avatarType=issuetype", name: "Affected Document", subtask: !0,avatarId: 11747}}},{id: "96466", key: "XYZ-24614", self: "foo.comjira/rest/api/2/issue/96466", fields: {summary: "Test 2", status: {self: "foo.comjira/rest/api/2/status/10338", description: "", iconUrl: "foo.comjira/images/icons/statuses/generic.png", name: "Current", id: "10338", statusCategory: {self: "foo.comjira/rest/api/2/statuscategory/4", id: 4,key: "indeterminate", colorName: "yellow", name: "In Progress"}},issuetype: {self: "foo.comjira/rest/api/2/issuetype/10319", id: "10319", description: "", iconUrl: "foo.comjira/secure/viewavatar?size=xsmall&avatarId=11747&avatarType=issuetype", name: "Affected Document", subtask: !0,avatarId: 11747}}}],Participants: [{name: "djcook2(djcook2xyz)"},{name: "swchambe(swchambexyz)"},{name: "r_slscdm(JIRAxyz)"}],reporter: {self: "foo.comjira/rest/api/2/user?username=djcook2", name: "djcook2", key: "djcook2", emailAddress: "[email protected]", displayName: "Deborah Jane Ott", active: !0,timeZone: "America/Chicago"},CPEOrganization: "xyz", SFSearchandViewLink: "<a href=foo.comportal/web/csa/search?key=95743&projectKey=XYZ&issueType=Change%20Request>S2D-0637</a>", progress: {progress: 0,total: 0},issuetype: {self: "foo.comjira/rest/api/2/issuetype/8", id: "8", description: "Request for a change to the way the application works.", iconUrl: "foo.comjira/secure/viewavatar?size=xsmall&avatarId=11737&avatarType=issuetype", name: "Change Request", subtask: !1,avatarId: 11737},project: {self: "foo.comjira/rest/api/2/project/13390", id: "13390", key: "XYZ", name: "Configuration Status Accounting", projectTypeKey: "business"},SFIdentifier: "S2D-0637", watches: {self: "foo.comjira/rest/api/2/issue/XYZ-24600/watchers", watchCount: 2,isWatching: !0},ServerEnvironment: [{self: "foo.comjira/rest/api/2/customFieldOption/10060", value: "Production", id: "10060", disabled: !1}],ScheduleImpact: {self: "foo.comjira/rest/api/2/customFieldOption/12245", value: "No", id: "12245", disabled: !1},MissionConfigurationDefinition: [{self: "foo.comjira/rest/api/2/customFieldOption/12246", value: "1110-1200", id: "12246", disabled: !1},{self: "foo.comjira/rest/api/2/customFieldOption/12247", value: "1110-2200", id: "12247", disabled: !1}],updated: "2022-05-23T10: 06: 45.000-0500", description: "¶ Paragraph\nNonbreaking   Hyphen\nEm Space\nEn Space\n½ One Half Fraction\n¼ One Quarter Fraction\n¾ Three Quarters Fraction\n10⁵ superscript\n6⁵ superscript\nO₂ subscript\n\n± 0177\n≤ 2264\n≥ 2265\n\n10⁰ - 2070\n10¹ - 00B9\n10³ - 00B3\n10² - 00B2\n10⁴ - 2074\n10⁵ - 2075\n10⁶ - 2076\n10⁷ - 2077\n10⁸ - 2078\n10⁹ - 2079\n\nΑ  0391\nΒ  0392\nΓ  0393\nΔ  0394\nΕ  0395", CRStatus: {self: "foo.comjira/rest/api/2/customFieldOption/10050", value: "In Work", id: "10050", disabled: !1},summary: "SLS-FSW-SAN-21-0010    SLS FSW Software Authorization Notice (SAN) - PARMD5 Support Tool Release 14.0", SLSPriority: {self: "foo.comjira/rest/api/2/customFieldOption/10347", value: "Routine", id: "10347", disabled: !1},TestStatus: [{self: "foo.comjira/rest/api/2/customFieldOption/10041", value: "Not Tested", id: "10041", disabled: !1}],ChangeJustificationRationale: "Looks good to me, but who am I?", CostImpact: {self: "foo.comjira/rest/api/2/customFieldOption/19251", value: "No", id: "19251", disabled: !1},ExternalReviewType: {self: "foo.comjira/rest/api/2/customFieldOption/10370", value: "Mandatory", id: "10370", disabled: !1},CROffice: {self: "foo.comjira/rest/api/2/customFieldOption/10342", value: "SLS", id: "10342", disabled: !1},Rank: "0|i0c9r8: ", CrossProgram: {self: "foo.comjira/rest/api/2/customFieldOption/10294", value: "No", id: "10294", disabled: !1},Programassignedto: {self: "foo.comjira/rest/api/2/customFieldOption/10295", value: "SLS", id: "10295", disabled: !1},Programassignedby: {self: "foo.comjira/rest/api/2/customFieldOption/10301", value: "SLS", id: "10301", disabled: !1},ChangeType: [{self: "foo.comjira/rest/api/2/customFieldOption/10307", value: "Programmatic", id: "10307", disabled: !1}],ChangePackageManagerCPM: {self: "foo.comjira/rest/api/2/user?username=swchambe", name: "swchambe", key: "swchambe", emailAddress: "[email protected]", displayName: "Sharon W Chamberlain", active: !0,timeZone: "America/Chicago"},ChangePackageManagerAlternateCPMAlternate: {self: "foo.comjira/rest/api/2/user?username=slcraig", name: "slcraig", key: "smclemo2", emailAddress: "[email protected]", displayName: "Shanda L Craig", active: !0,timeZone: "America/Chicago"},ChangePackageEngineerCPE: {self: "foo.comjira/rest/api/2/user?username=cbowab", name: "cbowab", key: "cbowab", emailAddress: "[email protected]", displayName: "Cheri F Bowab", active: !0,timeZone: "America/Chicago"},status: {self: "foo.comjira/rest/api/2/status/10631", description: "", iconUrl: "foo.comjira/images/icons/statuses/generic.png", name: "Draft", id: "10631"},Development: "{}", RequestedDate: "2021-05-13", Risk: {self: "foo.comjira/rest/api/2/customFieldOption/10273", value: "No", id: "10273", disabled: !1},creator: {self: "foo.comjira/rest/api/2/user?username=djcook2", name: "djcook2", key: "djcook2", emailAddress: "[email protected]", displayName: "Deborah Jane Ott", active: !0,timeZone: "America/Chicago"},aggregateprogress: {progress: 0,total: 0},AssigneeSecurityScan: {self: "foo.comjira/rest/api/2/user?username=sbattles", name: "sbattles", key: "sbattles", emailAddress: "[email protected]", displayName: "Sylvia M Battles", active: !0,timeZone: "America/Chicago"},Board: [{self: "foo.comjira/rest/api/2/customFieldOption/10259", value: "XYZ", id: "10259", disabled: !1}],MissionEffectivity: [{self: "foo.comjira/rest/api/2/customFieldOption/19754", value: "XYZ", id: "19754", disabled: !1},{self: "foo.comjira/rest/api/2/customFieldOption/19756", value: "AC01", id: "19756", disabled: !1}],CRNumber: [{name: "XYZ-0637"}],created: "2021-05-14T15: 14: 22.000-0500", ASCBBoardDate: "2021-05-18", InitiatorOrganization: "ED10", CPMAssignedDate: "2021-05-14", CRAssignedDate: "2021-05-14", ImpactstoCertifiedData: {self: "foo.comjira/rest/api/2/customFieldOption/20152", value: "No", id: "20152", disabled: !1},ASCBReviewSuspenseDate: "2021-05-18", TopLevelLinkTitle: "SV02854 S2D-0637", TopLevelLinkURL: "https: //nasa-ice.nasa.gov/Windchill/app/#ptc1/tcomp/infoPage?ContainerOid=OR%3Awt.inf.library.WTLibrary%3A3451955009&oid=OR%3Awt.folder.SubFolder%3A4352888087&u8=1", Initiator: {self: "foo.comjira/rest/api/2/user?username=kmoorhea", name: "kmoorhea", key: "kmoorhea", emailAddress: "[email protected]", displayName: "Kathy H Moorhead", active: !0,timeZone: "America/Chicago"}}}]}}

console .log (convert (input))
.as-console-wrapper {max-height: 100% !important; top: 0}

Here, makeFancyMenu does all the recursive heavy lifting, and convert simply wraps it in something that handles the differences at the root.

Instead of map we use flatMap and wrap its single callback returns in arrays so that in the case of an array property, we can just return an empty array. This is a simple way to combine filter and map.

Upvotes: 1

Related Questions