I have array of objects. All Objects and its children contain permission property array. I have to gather permission property values from children assign to corresponding parent. if multi children for a parent permissions of parent should all children's Permissions.
const navItems: any[] = [
{
text: 'Analytics',
imageUrl: '../assets/images/Qi-white.png',
permissions: [],
children: [
{
text: 'Reports',
icon: 'layout',
permissions: ['rep1'],
route: 'reports/reports',
},
{
text: 'NewSelectionPanel',
icon: 'layout',
permissions: ['rep2'],
route: 'reports/reportsNew',
},
],
},
{
text: 'Static Data',
icon: 'parameters',
permissions:[],
children: [
{
text: 'Geographic Defs',
permissions:[],
maticon: 'settings',
children: [
{
text: 'Country',
maticon: 'grid_view',
permissions: ['cou'],
route: 'static-data/country',
},
{
text: 'Country Allocation',
maticon: 'grid_view',
permissions: ['cou-allo'],
route: 'static-data/group-to-country',
}
],
},
{
text: 'Node Defs',
maticon: 'settings',
permissions:[],
children: [
{
text: 'Node Category',
maticon: 'grid_view',
permissions: ['no1'],
route: 'static-data/category',
},
{
text: 'Node Class',
maticon: 'grid_view',
permissions: ['no2'],
route: 'static-data/node-class',
},
{
text: 'Node Classification',
maticon: 'grid_view',
permissions: ['no3'],
route: 'static-data/classification',
}
],
},
],
}
];
After gathering permission Is should be following structure
const navItems: any[] = [
{
text: 'Analytics',
imageUrl: '../assets/images/Qi-white.png',
permissions: ['rep1','rep2'],
children: [
{
text: 'Reports',
icon: 'layout',
permissions: ['rep1'],
route: 'reports/reports',
},
{
text: 'NewSelectionPanel',
icon: 'layout',
permissions: ['rep2'],
route: 'reports/reportsNew',
},
],
},
{
text: 'Static Data',
icon: 'parameters',
permissions:['cou-allo','cou','no1','no2','no3'],
children: [
{
text: 'Geographic Defs',
permissions:['cou-allo','cou'],
maticon: 'settings',
children: [
{
text: 'Country',
maticon: 'grid_view',
permissions: ['cou'],
route: 'static-data/country',
},
{
text: 'Country Allocation',
maticon: 'grid_view',
permissions: ['cou-allo'],
route: 'static-data/group-to-country',
}
],
},
{
text: 'Node Defs',
maticon: 'settings',
permissions:['no1','no2','no3'],
children: [
{
text: 'Node Category',
maticon: 'grid_view',
permissions: ['no1'],
route: 'static-data/category',
},
{
text: 'Node Class',
maticon: 'grid_view',
permissions: ['no2'],
route: 'static-data/node-class',
},
{
text: 'Node Classification',
maticon: 'grid_view',
permissions: ['no3'],
route: 'static-data/classification',
}
],
},
],
}
];
You apparently want to mutate your object, which is blasphemy to the Gods of Immutability, Purity and Functional Programming.
On the other hand, since you're doomed no matter what, you can at least dispense with the ritual of duplicating everything and restricting JavaScript to a litany of chained array function.
Simple loops will do the trick nicely, without all this squandering of memory and CPU.
function GatherPermissions (input)
{
function flatten_permissions (item) {
// will merge two arrays and remove duplicates
/* If permissions are unique (i.e. you won't find the same permission in two different
children) and you use that function wisely (i.e. you call it only once), then you don't
need to enforce uniqueness and a simple "a.concat(b)" will be enough */
function merge_unique (a, b) {
return a.concat(b).filter((i, p, c) => c.indexOf(i) === p);
}
let flat_permissions = item.permissions ?? [];
for (child of item.children ?? []) {
flat_permissions = merge_unique (flat_permissions, flatten_permissions(child))
}
return item.permissions = flat_permissions; // mutation occurs there (booh!)
}
for (item of input) flatten_permissions(item);
}
Sample output using your input:
GatherPermissions (navItems);
console.log(`${JSON.stringify(navItems,undefined,4)}`);
[
{
"text": "Analytics",
"imageUrl": "../assets/images/Qi-white.png",
"permissions": [
"rep1",
"rep2"
],
"children": [
{
"text": "Reports",
"icon": "layout",
"permissions": [
"rep1"
],
"route": "reports/reports"
},
{
"text": "NewSelectionPanel",
"icon": "layout",
"permissions": [
"rep2"
],
"route": "reports/reportsNew"
}
]
},
{
"text": "Static Data",
"icon": "parameters",
"permissions": [
"cou",
"cou-allo",
"no1",
"no2",
"no3"
],
"children": [
{
"text": "Geographic Defs",
"permissions": [
"cou",
"cou-allo"
],
"maticon": "settings",
"children": [
{
"text": "Country",
"maticon": "grid_view",
"permissions": [
"cou"
],
"route": "static-data/country"
},
{
"text": "Country Allocation",
"maticon": "grid_view",
"permissions": [
"cou-allo"
],
"route": "static-data/group-to-country"
}
]
},
{
"text": "Node Defs",
"maticon": "settings",
"permissions": [
"no1",
"no2",
"no3"
],
"children": [
{
"text": "Node Category",
"maticon": "grid_view",
"permissions": [
"no1"
],
"route": "static-data/category"
},
{
"text": "Node Class",
"maticon": "grid_view",
"permissions": [
"no2"
],
"route": "static-data/node-class"
},
{
"text": "Node Classification",
"maticon": "grid_view",
"permissions": [
"no3"
],
"route": "static-data/classification"
}
]
}
]
}
]
Related
I have an array of objects with Name, Key in all objects and ParentKey in some of the objects.
I want to group objects by unique 'Key' excluding those which have 'ParentKey'. The objects having ParentKey should be nested as reflected in required ans.
Initial Input :-
const arr = [
{
Name: 'Manage Leads',
Key: 'Manage Leads',
},
{
Name: 'Dashboard',
Key: 'Dashboard',
},
{
Name: 'Smart Views',
Key: 'Smart Views',
},
{
Name: 'Lead Details',
Key: 'Lead Details',
},
{
Name: 'Opportunity Details',
Key: 'Opportunity Details',
},
{
Name: 'Header',
Key: 'Header',
},
{
Name: 'Settings',
Key: 'Settings',
},
{
Name: 'Test 1',
Key: 'Test1Key',
},
{
Name: 'Test 1.1',
Key: 'Test1.1Key',
ParentKey: 'Test1',
},
{
Name: 'Test 1.2',
Key: 'Test1.2Key',
ParentKey: 'Test1',
},
{
Name: 'Test 1.1.1',
Key: 'Test1.1.1Key',
ParentKey: 'Test 1.1',
},
{
Name: 'Test 1.1.2',
Key: 'Test1.1.2Key',
ParentKey: 'Test 1.1',
},
{
Name: 'Test 1.2.1',
Key: 'Test1.2.1Key',
ParentKey: 'Test 1.2',
},
];
Required Output :-
[
{
groupName: 'Manage Leads',
actionsArr: [{ Name: 'Manage Leads', Key: 'Manage Leads' }],
},
{
groupName: 'Dashboard',
actionsArr: [{ Name: 'Dashboard', Key: 'Dashboard' }],
},
{
groupName: 'Smart Views',
actionsArr: [{ Name: 'Smart Views', Key: 'Smart Views' }],
},
{
groupName: 'Lead Details',
actionsArr: [{ Name: 'Lead Details', Key: 'Lead Details' }],
},
{
groupName: 'Opportunity Details',
actionsArr: [
{
Name: 'Opportunity Details',
Key: 'Opportunity Details',
},
],
},
{
groupName: 'Header',
actionsArr: [{ Name: 'Header', Key: 'Header' }],
},
{
groupName: 'Settings',
actionsArr: [{ Name: 'Settings', Key: 'Settings' }],
},
{
groupName: 'Test1Key',
actionsArr: [
{
Name: 'Test 1',
Key: 'Test1Key',
subActions: [
{
Name: 'Test 1.1',
Key: 'Test1.1',
ParentKey: 'Test1Key',
subActions: [
{
Name: 'Test 1.1.1',
Key: 'Test1.1.1Key',
ParentKey: 'Test 1.1',
},
{
Name: 'Test 1.1.2',
Key: 'Test1.1.2Key',
ParentKey: 'Test 1.1',
},
],
},
{
Name: 'Test 1.2',
Key: 'Test1.2',
ParentKey: 'Test1Key',
subActions: [
{
Name: 'Test 1.2.1',
Key: 'Test1.2.1Key',
ParentKey: 'Test 1.2',
},
],
},
],
},
],
},
];
I was able to group by unique Key with the follwoing code but i'm not able to nest the objects which have ParentKey.
const groupNames = [...new Set(actions.map((item) => item.GroupKey))];
const actionsList = groupNames.map((groupName) => {
const actionsArr = actions.filter((act) => act.GroupKey === groupName);
return { label: groupName, value: actionsArr }});
I found some inconsistencies between Key and ParentKey for the given data.
I have fixed the inconsistencies in the input data, and I would be using the same.
Here is the solution that worked for me.
const arr = [
{
Name: "Manage Leads",
Key: "Manage Leads",
},
{
Name: "Dashboard",
Key: "Dashboard",
},
{
Name: "Smart Views",
Key: "Smart Views",
},
{
Name: "Lead Details",
Key: "Lead Details",
},
{
Name: "Opportunity Details",
Key: "Opportunity Details",
},
{
Name: "Header",
Key: "Header",
},
{
Name: "Settings",
Key: "Settings",
},
{
Name: "Test 1",
Key: "Test1Key",
},
{
Name: "Test 1.1",
Key: "Test1.1Key",
ParentKey: "Test 1",
},
{
Name: "Test 1.2",
Key: "Test1.2Key",
ParentKey: "Test 1",
},
{
Name: "Test 1.1.1",
Key: "Test1.1.1Key",
ParentKey: "Test 1.1",
},
{
Name: "Test 1.1.2",
Key: "Test1.1.2Key",
ParentKey: "Test 1.1",
},
{
Name: "Test 1.2.1",
Key: "Test1.2.1Key",
ParentKey: "Test 1.2",
},
];
//recursively look for the child and append child to parent
const appendChild = (parent, arr) => {
for (let index = 0; index < arr.length; index++) {
const childElement = arr[index];
if (childElement.ParentKey == parent.Name) {
appendChild(childElement, arr);
if (parent.subActions) {
parent.subActions.push(childElement);
} else {
parent.subActions = [childElement];
}
//remove the child from that list and match the index
arr.splice(index, 1);
index--;
}
}
};
//convert data into a parent-child hierarchy
const convert = (arr) => {
for (const parent of arr) {
appendChild(parent, arr);
}
//filter out items which has been already added as child/subActions
return arr.filter((x) => !Boolean(x.ParentKey));
};
const groupBy = (items, callback) => {
const groupedData = items.reduce(
(acc, value, index) => (
(acc[callback(value, index, items)] ||= []).push(value), acc
),
{}
);
//convert grouped data as the required output
return Object.entries(groupedData).map(([key, value]) => ({
groupName: key,
actionsArr: value,
}));
};
const data = groupBy(convert(arr), (x) => x.Name);
console.log(JSON.stringify(data, null, 2));
Output:
[
{
"groupName": "Manage Leads",
"actionsArr": [
{
"Name": "Manage Leads",
"Key": "Manage Leads"
}
]
},
{
"groupName": "Dashboard",
"actionsArr": [
{
"Name": "Dashboard",
"Key": "Dashboard"
}
]
},
{
"groupName": "Smart Views",
"actionsArr": [
{
"Name": "Smart Views",
"Key": "Smart Views"
}
]
},
{
"groupName": "Lead Details",
"actionsArr": [
{
"Name": "Lead Details",
"Key": "Lead Details"
}
]
},
{
"groupName": "Opportunity Details",
"actionsArr": [
{
"Name": "Opportunity Details",
"Key": "Opportunity Details"
}
]
},
{
"groupName": "Header",
"actionsArr": [
{
"Name": "Header",
"Key": "Header"
}
]
},
{
"groupName": "Settings",
"actionsArr": [
{
"Name": "Settings",
"Key": "Settings"
}
]
},
{
"groupName": "Test 1",
"actionsArr": [
{
"Name": "Test 1",
"Key": "Test1Key",
"subActions": [
{
"Name": "Test 1.1",
"Key": "Test1.1Key",
"ParentKey": "Test 1",
"subActions": [
{
"Name": "Test 1.1.1",
"Key": "Test1.1.1Key",
"ParentKey": "Test 1.1"
},
{
"Name": "Test 1.1.2",
"Key": "Test1.1.2Key",
"ParentKey": "Test 1.1"
}
]
},
{
"Name": "Test 1.2",
"Key": "Test1.2Key",
"ParentKey": "Test 1",
"subActions": [
{
"Name": "Test 1.2.1",
"Key": "Test1.2.1Key",
"ParentKey": "Test 1.2"
}
]
}
]
}
]
}
]
I can't figure out how to properly use .filter() to find an object in an Array by searching for a value in its nested Array.
I have the following data:
const orders = [
{
id: 1,
items: [
{
itemId: "abc",
},
{
itemId: "def",
},
],
},
{
id: 2,
items: [
{
itemId: "jkl",
},
{
itemId: "mno",
},
],
},
{
id: 3,
items: [
{
itemId: "abc",
},
{
itemId: "xyz",
},
],
},
];
I have the needed itemId: "abc" which I need to use to find all the objects that have items that also have the Id of "abc", so that the result is this:
[
{
id: 1,
items: [
{
itemId: "abc",
},
{
itemId: "def",
},
],
},
{
id: 3,
items: [
{
itemId: "abc",
},
{
itemId: "xyz",
},
],
},
]
So far, I've tried the following:
orders &&
orders.filter((order) => {
return order.items.filter((item) => item.itemId === "abc");
});
But it doesn't seem to work. What am I missing here?
Chris G beat me to it in the comments but he is right, you need to use order.items.some in your inner function:
const orders = [{
id: 1,
items: [{
itemId: "abc",
},
{
itemId: "def",
},
],
},
{
id: 2,
items: [{
itemId: "jkl",
},
{
itemId: "mno",
},
],
},
{
id: 3,
items: [{
itemId: "abc",
},
{
itemId: "xyz",
},
],
},
]
var ans = orders.filter((order) => {
return order.items.some((item) => item.itemId === "abc");
});
console.log(ans)
const orders = [{
id: 1,
items: [{
itemId: "abc",
},
{
itemId: "def",
},
],
},
{
id: 2,
items: [{
itemId: "jkl",
},
{
itemId: "mno",
},
],
},
{
id: 3,
items: [{
itemId: "abc",
},
{
itemId: "xyz",
},
],
},
];
const result = orders.filter(order =>
order.items.find(item => item.itemId === 'abc') !== undefined
)
console.log(result);
I have an access JSON object like below
{
"data": [
{
"label": "Self Service",
"data": {
"roles": [
"Employee",
"Manager",
"System Administrator"
]
},
"children": [
{
"label": "Attendance",
"icon": "pi pi-file",
"data": {
"roles": [
"Employee",
"System Administrator"
]
},
"children": [
{
"label": "Clocking",
"icon": "pi pi-file",
"data": {
"roles": [
"Employee",
"System Administrator"
],
"routerLink": ["ESS-ATT-clocking"]
}
},
{
"label": "History",
"icon": "pi pi-file",
"data": {
"roles": [
"Employee",
"System Administrator"
]
}
}
]
},
{
"label": "Claim",
"icon": "pi pi-file",
"data": {
"roles": [
"Manager",
"System Administrator"
]
},
"children": [
{
"label": "Entitlement & Request",
"icon": "pi pi-file",
"data": {
"roles": [
"Manager",
"System Administrator"
]
}
}
]
}
]
},
]
}
stored in a variable accessCtrl. I have another variable
role = "Employee"
Each child node is connected with "children" property.
How can i loop through (recursively) to remove the whole JSON object, "accessCtrl" and remove the particular node, if the "role" is not exists in data.role array?
e.g.
role = "Manager"
the object should return
{
"data": [
{
"label": "Self Service",
"data": {
"roles": [
"Employee",
"Manager",
"System Administrator"
]
},
"children": [
{
"label": "Claim",
"icon": "pi pi-file",
"data": {
"roles": [
"Manager",
"System Administrator"
]
},
"children": [
{
"label": "Entitlement & Request",
"icon": "pi pi-file",
"data": {
"roles": [
"Manager",
"System Administrator"
]
}
}
]
}
]
},
]
}
This is my current code and it doesn't seems work correctly.
function removeNode(obj, parent) {
for (let prop in obj) {
if (
prop === "data" &&
prop.hasOwnProperty("roles") &&
!prop.roles.includes(this.role)
) {
if (parent) {
delete parent.children;
}
} else if (typeof obj[prop] === "object") removeNode(obj[prop], obj);
}
}
removeNode(this.accessCtrl, null);
console.log("this.accessCtrl=", this.accessCtrl);
For a function to be recursive, it needs to call itself.
Please let me know if you need more explanation on how it works.
const input = {
"data": [{
"label": "Self Service",
"data": {
"roles": [
"Employee",
"Manager",
"System Administrator"
]
},
"children": [{
"label": "Attendance",
"icon": "pi pi-file",
"data": {
"roles": [
"Employee",
"System Administrator"
]
},
"children": [{
"label": "Clocking",
"icon": "pi pi-file",
"data": {
"roles": [
"Employee",
"System Administrator"
],
"routerLink": ["ESS-ATT-clocking"]
}
},
{
"label": "History",
"icon": "pi pi-file",
"data": {
"roles": [
"Employee",
"System Administrator"
]
}
}
]
},
{
"label": "Claim",
"icon": "pi pi-file",
"data": {
"roles": [
"Manager",
"System Administrator"
]
},
"children": [{
"label": "Entitlement & Request",
"icon": "pi pi-file",
"data": {
"roles": [
"Manager",
"System Administrator"
]
}
}]
}
]
}]
}
const role = "Manager";
const removeRoles = (tree, role) => {
const newTree = []
for (const item of tree) {
if (item.data.roles.includes(role)) {
if (item.children) {
item.children = removeRoles(item.children, role) // this is where it gets recursive
}
newTree.push(item)
}
}
return newTree;
}
const result = { data: removeRoles(input.data, role) }
console.log(result);
I would separate out the code that filters your recursive array from the actual code that tests the business requirement (here that's ({data: {roles}}) => roles .includes ('Manager').) Here's one possibility:
const filterDeep = (pred) => (xs) =>
xs .flatMap (x => pred (x)
? [{... x, children: filterDeep (pred) (x .children || [])}]
: []
)
const justManagers = (({data, ...rest}) => ({
...rest,
data: filterDeep (({data: {roles}}) => roles .includes ('Manager')) (data)
}))
const input = {data: [{label: "Self Service", data: {roles: ["Employee", "Manager", "System Administrator"]}, children: [{label: "Attendance", icon: "pi pi-file", data: {roles: ["Employee", "System Administrator"]}, children: [{label: "Clocking", icon: "pi pi-file", data: {roles: ["Employee", "System Administrator"], routerLink: ["ESS-ATT-clocking"]}}, {label: "History", icon: "pi pi-file", data: {roles: ["Employee", "System Administrator"]}}]}, {label: "Claim", icon: "pi pi-file", data: {roles: ["Manager", "System Administrator"]}, children: [{label: "Entitlement & Request", icon: "pi pi-file", data: {roles: ["Manager", "System Administrator"]}}]}]}]}
console .log (
justManagers (input)
)
.as-console-wrapper {max-height: 100% !important; top: 0}
filterDeep does the recursive tree walking and includes only those nodes that match our predicate. justManager does a little juggling of the input structure so that we can focus only on the data property and then calls filterDeep passing it our predicate that tests whether our node has the "Manager" role. It leaves any other properties of our input data intact.
Here is a solution using object-scan. We use object-scan for our data processing, but it does take a moment to wrap your head around. Conceptually the solution is simple: We check "leaf first" and then work up the hierarchy and delete if (1) no children are present and (2) desired role is not present
// const objectScan = require('object-scan');
const input = { data: [{ label: 'Self Service', data: { roles: ['Employee', 'Manager', 'System Administrator'] }, children: [{ label: 'Attendance', icon: 'pi pi-file', data: { roles: ['Employee', 'System Administrator'] }, children: [ { label: 'Clocking', icon: 'pi pi-file', data: { roles: ['Employee', 'System Administrator'], routerLink: ['ESS-ATT-clocking'] } }, { label: 'History', icon: 'pi pi-file', data: { roles: ['Employee', 'System Administrator'] } } ] }, { label: 'Claim', icon: 'pi pi-file', data: { roles: ['Manager', 'System Administrator'] }, children: [ { label: 'Entitlement & Request', icon: 'pi pi-file', data: { roles: ['Manager', 'System Administrator'] } } ] }] }] };
const prune = (role, data) => objectScan(['{data,**.children}[*]'], {
rtn: 'count',
filterFn: ({ value, property, parent }) => {
if (
!value.data.roles.includes(role)
&& (value.children || []).length === 0
) {
parent.splice(property, 1);
return true;
}
return false;
}
})(data);
console.log(prune('Manager', input)); // return number of deletions
// => 3
console.log(input);
/* => { data: [
{
label: 'Self Service',
data: { roles: [ 'Employee', 'Manager', 'System Administrator' ] },
children: [
{ label: 'Claim', icon: 'pi pi-file', data: { roles: [ 'Manager', 'System Administrator' ] }, children: [
{ label: 'Entitlement & Request', icon: 'pi pi-file', data: { roles: [ 'Manager', 'System Administrator' ] } }
] }
]
}
] } */
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="https://bundle.run/object-scan#13.8.0"></script>
Disclaimer: I'm the author of object-scan
I have faced a situation where I have two JavaScript objects:
Input object:
{
name:"a1",
children:[
{name:"P", value:'newVal1'},
{name:"Q", value:'newVal2'},
{name:"R", value:'newVal3'},
{name:"S1", children:[
{name:"T", value:"newVal4"}
]},
]
}
Template:
{
name: "a1",
children: [
{
name: "b1",
children: [
{
name: "c1",
children: [
{
name: "P"
},
],
},
{
name: "b2",
children: [
{
name: "c2",
children: [
{
name: "Q"
},
],
},
{
name: "b3",
children: [
{
name: "R"
},
],
},
{
name: "b4",
children: [
,
{
name: "c3",
children: [
,
{
name: "s1",
children: [
{
name: "e1",
children: [
{
name: "T"
},
],
},
],
},
],
},
],
},
],
},
],
},
],
}
I need to merge the input object into the template object such that the new values would be:
{
name: "a1",
children: [
{
name: "b1",
children: [
{
name: "c1",
children: [
{
name: "P",
value: "newVal1",
},
],
},
{
name: "b2",
children: [
{
name: "c2",
children: [
{
name: "Q",
value: "newVal2",
},
],
},
{
name: "b3",
children: [
{
name: "R",
value: "newVal3",
},
],
},
{
name: "b4",
children: [
,
{
name: "c3",
children: [
,
{
name: "s1",
children: [
{
name: "e1",
children: [
{
name: "T",
value: "newVal4",
},
],
},
],
},
],
},
],
},
],
},
],
},
],
}
Notice how newVal1 etc. values have to land up in the correct spots in the merged structure.
The intermediate layers (a,b,c etc.) may or may not exist, i.e. there might be many layers in-between before matching the P Q R layers, or on the other side, a given template object may exactly match the structure of the input, and the function/class should still be able to place values inside.
I am using Typescript, but even a JavaScript answer is welcome.
Also, does this sort of object matching have a name?
Really appreciate your time. Thanks.
guys i have this json
var menu = [{
name: 'Computers',
children: [{
name: 'Notebook'
children: [{
name: 'Apple'
}, {
name: 'Windows'
}]
}, {
name: Tablets
children: [{
name: 'Apple'
}, {
name: 'Android'
}, {
name: 'Windows'
}]
}]
}, {
name: 'Phones',
children: [{
name: 'Android'
children: [{
name: 'Samsung'
}, {
name: 'Nokia'
}, {
name: 'Lenovo'
}]
}, {
name: 'Windows Phones'
children: [{
name: 'Microsoft'
}, {
name: 'Nokia'
}]
}]
}, {
name: 'Cameras',
children: [{
name: 'Digital'
children: [{
name: 'Nikon'
}, {
name: 'Fuji'
}]
}, {
name: 'DSLR'
children: [{
name: 'Canon'
}, {
name: 'Nikon'
}]
}]
}];
it says it is not valid json ... so how to make it valid json ??
any help would be appreciated ... thanks a lot
btw i am beginner so please help me
any suggestions ?? thanks again :)
You have some missing commas, where noted and a suposed to be a string without delimiters in your object literal.
var menu = [{
name: 'Computers',
children: [{
name: 'Notebook', // missing ,
children: [{
name: 'Apple'
}, {
name: 'Windows'
}]
}, {
name: 'Tablets', // missing string delimiter and comma
children: [{
name: 'Apple'
}, {
name: 'Android'
}, {
name: 'Windows'
}]
}]
}, {
name: 'Phones',
children: [{
name: 'Android', // missing ,
children: [{
name: 'Samsung'
}, {
name: 'Nokia'
}, {
name: 'Lenovo'
}]
}, {
name: 'Windows Phones', // missing ,
children: [{
name: 'Microsoft'
}, {
name: 'Nokia'
}]
}]
}, {
name: 'Cameras',
children: [{
name: 'Digital', // missing ,
children: [{
name: 'Nikon'
}, {
name: 'Fuji'
}]
}, {
name: 'DSLR', // missing ,
children: [{
name: 'Canon'
}, {
name: 'Nikon'
}]
}]
}];
console.log(menu);
.as-console-wrapper { max-height: 100% !important; top: 0; }
There are two problems
After name property values, comma is missing (at various places)
Tablets is not in quotes
Correct syntax would be.
var menu = [{
name: 'Computers',
children: [{
name: 'Notebook',
children: [{
name: 'Apple'
}, {
name: 'Windows'
}]
}, {
name: 'Tablets',
children: [{
name: 'Apple'
}, {
name: 'Android'
}, {
name: 'Windows'
}]
}]
}, {
name: 'Phones',
children: [{
name: 'Android',
children: [{
name: 'Samsung'
}, {
name: 'Nokia'
}, {
name: 'Lenovo'
}]
}, {
name: 'Windows Phones',
children: [{
name: 'Microsoft'
}, {
name: 'Nokia'
}]
}]
}, {
name: 'Cameras',
children: [{
name: 'Digital',
children: [{
name: 'Nikon'
}, {
name: 'Fuji'
}]
}, {
name: 'DSLR',
children: [{
name: 'Canon'
}, {
name: 'Nikon'
}]
}]
}];
You can copy your code is chrome's console to see where the error is.
you need to put double quotes on key an value like this "key" : "value"
[{
"name": "Computers",
"children": [{
"name": "Notebook",
"children": [{
"name": "Apple"
}, {
"name": "Windows"
}]
}, {
"name": "Tablets",
"children": [{
"name": "Apple"
}, {
"name": "Android"
}, {
"name": "Windows"
}]
}]
}]
And after name property values, comma is missing (at various places)
key and value should be wrapped by double quotes
copy paste the code validate here https://jsonformatter.curiousconcept.com/
[
{
"name":"Computers",
"children":[
{
"name":"Notebook",
"children":[
{
"name":"Apple"
},
{
"name":"Windows"
}
]
},
{
"name":"Tablets",
"children":[
{
"name":"Apple"
},
{
"name":"Android"
},
{
"name":"Windows"
}
]
}
]
},
{
"name":"Phones",
"children":[
{
"name":"Android",
"children":[
{
"name":"Samsung"
},
{
"name":"Nokia"
},
{
"name":"Lenovo"
}
]
},
{
"name":"Windows Phones",
"children":[
{
"name":"Microsoft"
},
{
"name":"Nokia"
}
]
}
]
},
{
"name":"Cameras",
"children":[
{
"name":"Digital",
"children":[
{
"name":"Nikon"
},
{
"name":"Fuji"
}
]
},
{
"name":"DSLR",
"children":[
{
"name":"Canon"
},
{
"name":"Nikon"
}
]
}
]
}
]