Ancestors path to be reformat for hierarchy nodes object - javascript

I had reformat my data in mongodb using ancestors path to ensure the relationship of each nodes & intend to show it in a organisation tree view.
[
{
"isActive": true,
"ancestorsPath": [],
"studentGroup": [
"t2-001",
"t2-002",
"t2-003"
],
"_id": "33d9704f34901855c911e433",
"email": "user5#test.com",
"agentId": "t1-001"
},
{
"isActive": true,
"ancestorsPath": [],
"studentGroup": [
"t2-101",
"t2-102",
"t2-103"
],
"_id": "5cdb0664c409e90e4fe21133",
"email": "user5#test.com",
"agentId": "t1-100",
},
{
"isActive": true,
"ancestorsPath": [
"t1-001"
],
"studentGroup": [
"t3-001",
"t3-002",
"t3-003"
],
"_id": "5cdb06dec409e90e4fe21134",
"email": "user5#test.com",
"agentId": "t2-001",
}
]
However the data in organisation tree is using a format as below:
id: "T1-001",
name: "user5#test.com",
title: "general manager",
children: [
{
id: "t2-001",
name: "Bo Miao",
title: "department manager",
number: "MYR 2,000"
},
{
id: "t2-002",
name: "Su Miao",
title: "department manager",
children: [
{ id: "t3-001", name: "Tie Hua", title: "senior engineer" },
{
id: "t3-002",
name: "Hei Hei",
title: "senior engineer",
children: [
{ id: "6", name: "Pang Pang", title: "engineer" },
{ id: "7", name: "Xiang Xiang", title: "UE engineer" }
]
}
]
},
{ id: "t2-003", name: "Hong Miao", title: "department manager" }
How should I format my data? Can anyone give me some pointers so i can study further?

Related

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": "sharon.w.chamberlain#foo.com",
"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": "deborah.j.ott#foo.com",
"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": "sharon.w.chamberlain#foo.com",
"displayName": "Sharon W Chamberlain",
"active": true,
"timeZone": "America/Chicago"
},
"ChangePackageManagerAlternateCPMAlternate": {
"self": "foo.comjira/rest/api/2/user?username=slcraig",
"name": "slcraig",
"key": "smclemo2",
"emailAddress": "shanda.craig#foo.com",
"displayName": "Shanda L Craig",
"active": true,
"timeZone": "America/Chicago"
},
"ChangePackageEngineerCPE": {
"self": "foo.comjira/rest/api/2/user?username=cbowab",
"name": "cbowab",
"key": "cbowab",
"emailAddress": "cheri.f.bowab#foo.com",
"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": "deborah.j.ott#foo.com",
"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": "sylvia.battles#foo.com",
"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": "kathy.h.moorhead#foo.com",
"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.
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: "sharon.w.chamberlain#foo.com", 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: "deborah.j.ott#foo.com", 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: "sharon.w.chamberlain#foo.com", displayName: "Sharon W Chamberlain", active: !0,timeZone: "America/Chicago"},ChangePackageManagerAlternateCPMAlternate: {self: "foo.comjira/rest/api/2/user?username=slcraig", name: "slcraig", key: "smclemo2", emailAddress: "shanda.craig#foo.com", displayName: "Shanda L Craig", active: !0,timeZone: "America/Chicago"},ChangePackageEngineerCPE: {self: "foo.comjira/rest/api/2/user?username=cbowab", name: "cbowab", key: "cbowab", emailAddress: "cheri.f.bowab#foo.com", 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: "deborah.j.ott#foo.com", 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: "sylvia.battles#foo.com", 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: "kathy.h.moorhead#foo.com", 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.

Mongoose update subdocument by key

for the following collection:
id: Number
name:[
new Schema({
language: { type: String, enum: ['en-US', 'fr-CA'] },
text: String,
},{ _id: false }
);
],
isActive: Boolean
and sample data like the following:
{
id:1,
"name": [
{"language": "en-US", "text": "Book"},
{"language": "fr-CA", "text": "livre"}
],
isActive:true
// and so many other fields
},
{
id:2,
"name": [
{"language": "en-US", "text": "Pen"}
],
isActive:true
// and so many other fields
}
I would like to update the document by Id:1 and change the text only for french, I tried by:
const input={ "id":"1", "isActive": false}
const name= { "name": [{"language": "fr-CA", "text": "Nouvel article"}]}
await langs.findByIdAndUpdate(
{ _id: input.id },
{ ...input, $addToSet: { name } },
{ new: true, upsert: true }
);
but the result is: (added another french item)
{
id:1,
"name": [
{"language": "en-US", "text": "Book"},
{"language": "fr-CA", "text": "livre"},
{"language": "fr-CA", "text": "Nouvel article"}
],
isActive:false
},
This is based on Brit comment:
https://mongoplayground.net/p/atlw5ZKoYiI
Please advise.
As long as that attribute already exists on the document, you can do something like:
Collection.findOneAndUpdate({id: 1}, {
$set: {
"name.$[elem]": name
}
},
{
arrayFilters: [ { "elem.language": name.language } ],
upsert: true,
new: true
})

Return name and id property value of all arrays inside object

How to return name and id property value of all arrays? The idea is to make a single map of all these arrays and return the id and name?
Something like this
filters.[key].map((option, index) => (
<ItemFilter key={index}>{option}</ItemFilter>
))
I have this array object
filters: {
"services": [
{
"id": "1b975589-7111-46a4-b433-d0e3c0d7c08c",
"name": "Bank"
},
{
"id": "91d4637e-a17f-4b31-8675-c041fe06e2ad",
"name": "Income"
}
],
"accountTypes": [
{
"id": "1f34205b-2e5a-430e-982c-5673cbdb3a68",
"name": "Digital Account"
}
],
"channels": [
{
"id": "875f8350-073e-4a20-be20-38482a86892b",
"name": "Chat"
}
]
}
You can use flatMap or flat to achieve the desired result.
Object.values(obj.filters).flatMap(v => v)
or
Object.values(obj.filters).flat()
const obj = {
filters: {
services: [
{
id: "1b975589-7111-46a4-b433-d0e3c0d7c08c",
name: "Bank",
},
{
id: "91d4637e-a17f-4b31-8675-c041fe06e2ad",
name: "Income",
},
],
accountTypes: [
{
id: "1f34205b-2e5a-430e-982c-5673cbdb3a68",
name: "Digital Account",
},
],
channels: [
{
id: "875f8350-073e-4a20-be20-38482a86892b",
name: "Chat",
},
],
},
};
const result = Object.values(obj.filters).flatMap(v => v);
console.log(result);
If option is referring to name in your example code it could look something like this:
Object.values(
{
filters: {
services: [
{
id: "1b975589-7111-46a4-b433-d0e3c0d7c08c",
name: "Bank",
},
{
id: "91d4637e-a17f-4b31-8675-c041fe06e2ad",
name: "Income",
},
],
accountTypes: [
{
id: "1f34205b-2e5a-430e-982c-5673cbdb3a68",
name: "Digital Account",
},
],
channels: [
{
id: "875f8350-073e-4a20-be20-38482a86892b",
name: "Chat",
},
],
},
}.filters
)
.flat()
.map(({ name, index }) => <ItemFilter key={index}>{name}</ItemFilter>);

How can I fully merge two tree objects with spread operator?

I am trying to merge two tree objects into one with the spread operator, but I am not getting the correct merged result.
How can I fully merge two tree objects with spread operator ?
const tree1 = [{
comments: [{
text: "This a comment for case law 84",
id: "84"
}, {
text: "This a comment for case law 89",
id: "89"
}],
children: [{
comments: [{
text: "This a comment for case law 70",
id: "70"
}],
children: [{
comments: [{
text: "This a comment for case law 83",
id: "83"
}]
}]
}]
}];
const tree2 = [{
comments: [{
text: "This a comment for case law 184",
id: "184"
}],
children: [{
comments: [{
text: "This a comment for case law 170",
id: "170"
}],
children: [{
comments: [{
text: "This a comment for case law 183",
id: "183"
}]
}]
}]
}];
const mergedTrees = [{ ...tree2, ...tree1 }];
console.log("mergedTrees", mergedTrees);
The problem is while merging the properties with the same key get overwritten. The rightmost property has the highest precedence.
What I need to get this kind of merge? :
{
"0": {
"comments": [
{
"text": "This a comment for case law 84",
"id": "84"
},
{
"text": "This a comment for case law 89",
"id": "89"
},
{
"text": "This a comment for case law 184",
"id": "184"
}
],
"children": [
{
"comments": [
{
"text": "This a comment for case law 70",
"id": "70"
},
{
"text": "This a comment for case law 170",
"id": "170"
}
],
"children": [
{
"comments": [
{
"text": "This a comment for case law 83",
"id": "83"
},
{
"text": "This a comment for case law 183",
"id": "183"
}
]
}
]
}
]
}
}
if it's not possible with the spread operator and there is another way to make it, please let me know.
adding a link for tries: https://stackblitz.com/edit/fffika?file=index.ts
You could merge the arrays index-wise and take the same approach for nested children.
const
merge = (a, b) => [a, b].reduce((r, array) => {
array.forEach(({ children, ...o }, i) => {
r[i] ??= { };
Object.entries(o).forEach(([k, v]) => (r[i][k] ??= []).push(...v));
if (children) r[i].children = merge(r[i].children || [], children);
});
return r;
}, []),
tree1 = [{ comments: [{ text: "This a comment for case law 84", id: "84" }], news: [{ text: "This news 1 ", id: "1" }], children: [{ comments: [{ text: "This a comment for case law 70", id: "70" }], news: [{ text: "This news 2 ", id: "2" }, { text: "This news 3 ", id: "3" }], children: [{ comments: [{ text: "This a comment for case law 83", id: "83" }], news: [{ text: "This news 4 ", id: "4" }] }] }] }],
tree2 = [{ comments: [{ text: "This a comment for case law 184", id: "184" }], news: [{ text: "This news 12 ", id: "12" }, { text: "This news 13 ", id: "13" }], children: [{ comments: [{ text: "This a comment for case law 170", id: "170" }], news: [{ text: "This news 22 ", id: "22" }, { text: "This news 33", id: "33" }], children: [{ comments: [{ text: "This a comment for case law 183", id: "183" }], news: [{ text: "This news 122 ", id: "122" }, { text: "This news 133 ", id: "133" }] }] }] }]
result = merge(tree1, tree2);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Handling an array of object with variable structure

I have an array of object that defines file and directory structure. It will vary according to reality, which may be more complicated.
Here is an example :
For example this root folder contains "folder_id": "F1" and "folder_id": "F2", and it will continue to divide ...
const folders = [
{
folder_id: "F1",
name: "Test Folder 1",
files: [
{
file_id: "File1",
name: "Whiteboard-Jun 3rd 2020, 4:56 pm"
}
],
folders: [
{
folder_id: "Folder1",
name: "Sub Folder",
files: [
{
file_id: "File1-1",
name: "New Microsoft Word Document.docx"
}
],
folders: [
{
folder_id: "Folder1-1",
name: "Folder Grade 2",
files: [
{
file_id: "File1-1-1",
name: "Test file in Folder Grade 3"
}
],
folders: [
{
folder_id: "Folder1-1-1",
name: "Folder Grade 3",
files: [],
folders: []
}
]
}
]
}
]
},
{
folder_id: "F2",
name: "Test Folder 2",
files: [
{
file_id: "File2",
name: "buildcode.png"
}
],
folders: [
{
folder_id: "Folder2",
name: "Sub folder 1",
files: [
{
file_id: "File2-1",
name: "repo.png"
}
],
folders: []
}
]
}
];
I want the output to look like this:
{
my-root-id:{
childrenIds:[
0: "F1",
1: "F2"
],
id: "my-root-id"
},
F1:{
childrenIds:[
0: "File1",
1: "Folder1"
],
parentId: "my-root-id",
id: "F1"
},
F2:{
childrenIds:[
0: "File2",
1: "Folder2"
],
parentId: "my-root-id",
id: "F2"
},
File1:{
parentId: "File1",
id: "F1"
},
Folder1:{
childrenIds:[
0: "File1-1",
1: "Folder1-1"
],
parentId: "F1",
id: "Folder1"
},
Folder1-1:{
childrenIds:[
0: "File1-1-1",
1: "Folder1-1-1"
],
parentId: "Folder1",
id: "Folder1-1"
},
Folder2:{
childrenIds:[
0: "File2-1",
],
parentId: "F2",
id: "Folder2"
},
File2-1:{
parentId: "Folder2",
id: "File2-1"
}
}
The output above describes the relationship of each folder and file in the entire directory tree.
They need information like :
childrenIds: the folders and files it contains
parentId: Its parent directory
id: id by itself
How to do it. thank you
Don't know this actually works for you or not but output as you look for
let data = {
folders: [
{
folder_id: "F1",
name: "Test Folder 1",
files: [
{
file_id: "File1",
name: "Whiteboard-Jun 3rd 2020, 4:56 pm",
},
],
folders: [
{
folder_id: "Folder1",
name: "Sub Folder",
files: [
{
file_id: "File1-1",
name: "New Microsoft Word Document.docx",
},
],
folders: [
{
folder_id: "Folder1-1",
name: "Folder Grade 2",
files: [
{
file_id: "File1-1-1",
name: "Test file in Folder Grade 3",
},
],
folders: [
{
folder_id: "Folder1-1-1",
name: "Folder Grade 3",
files: [],
folders: [],
},
],
},
],
},
],
},
{
folder_id: "F2",
name: "Test Folder 2",
files: [
{
file_id: "File2",
name: "buildcode.png",
},
],
folders: [
{
folder_id: "Folder2",
name: "Sub folder 1",
files: [
{
file_id: "File2-1",
name: "repo.png",
},
],
folders: [],
},
],
},
],
};
const mapper = (folders, parentId) => {
let obj = {};
if (folders.length) {
folders.forEach((f) => {
if (f.folders) {
let _c = {
[f.folder_id]: {
childrenIds: f.files.map((_f) => _f.file_id),
...(parentId && { parentId }),
id: f.folder_id,
},
};
let _files = f.files.map((_f) => {
return {
[_f.file_id]: { ...(parentId && { parentId }), id: _f.file_id },
};
});
obj = { ...obj, ..._files["0"], ..._c, ...mapper(f.folders, f.folder_id) };
}
});
}
return obj;
};
console.log(mapper(data.folders));

Categories