'Get value of parent Object
Is there any way to get a key-value from an object's parent object? In the example below, I want to combine urlParent with section:
const linkItems = [
{
id: 1,
name: 'Home Page',
urlParent: '/home',
subItems: [
{
subId: 1,
name: 'Project 1',
section: '#project1',
get url() {
//output /home#project1
}
}
]
}
];
console.log(linkItems[0].subItems[0].url) // /home#project1;
Solution 1:[1]
You cannot reference an Object parent that way (Object(value) ? Array ? Object), and not even from an Object's parent Object.
What you can do instead is:
- Create two Classes, one for the parent and one for the child.
- When adding a child to the parent, just make a "linked list", by referencing the parent's
thisto the created child itemparentproperty
class Child {
constructor(data) {
Object.assign(this, data);
}
get url() {
return this.parent.urlParent + this.section
}
}
class Parent {
constructor(data) {
Object.assign(this, data);
this.subItems = [];
}
addChild(item) {
this.subItems.push(new Child({...item, parent: this}));
}
}
// Example:
const parent = new Parent({id:1, name:"Home", urlParent:"/home"});
parent.addChild({subId:1, name:"Project 1", section:"#project1"});
console.log(parent.subItems[0].url) // /home#project1;
But hey! Nodes and trees
Your original idea and the above use too much complexity.
What I'd suggest is to treat all parent, child, whatever, as Page Nodes.
class Page {
constructor(data) {
Object.assign(this, data);
this.children = {};
}
addChild(page) {
page.parent = this; // Linked to parent!
this.children[page.id] = page;
}
get url() {
// Generate full URI by recursing the parents tree
return this.parent ? `${this.parent.url}/${this.slug}` : this.slug;
}
}
// Example:
// 1. Create pages:
const pageRoot = new Page({id:1, name:"Home page", slug:""});
const pageProj = new Page({id:3, name:"All projects", slug:"projects"});
const pageWebs = new Page({id:4, name:"Websites", slug:"websites"});
const pageStOv = new Page({id:6, name:"Stack Overflow", slug:"so"});
const pageSpec = new Page({id:9, name:"Stack Overflow Specs", slug:"specs"});
// 2. Create Tree:
pageRoot.addChild(pageProj);
pageProj.addChild(pageWebs);
pageWebs.addChild(pageStOv);
pageStOv.addChild(pageSpec);
// 3. Test
console.log(pageRoot.url); // "";
console.log(pageProj.url); // "/projects";
console.log(pageSpec.url); // "/projects/websites/so/specs";
console.log(pageRoot);
Solution 2:[2]
const linkItems = [
{
id: 1,
name: 'Home Page',
urlParent: '/home',
get subItems(){
console.log(this.name);
return ([
(() => {
console.log(this);
return {
subId: 1,
name: 'Project 1',
section: '#project1',
urlParentFromOuterScope: () => {
return this.urlParent;
},
sectionString(){
return this.section;
},
url(){
console.log('url', this);
return this.urlParentFromOuterScope() + this.sectionString();
}
}
})()
])
}
}
];
const subItems = linkItems[0].subitems;
console.log(linkItems[0].subItems[0].url());
Please feel free to remove the unnecessary 'console.log's after you understand the approach. I took the liberty of adding a few methods. This is a tricky one and has to do with the scope of this in array functions. P.S.: I guess this can be simplified.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Hemanth788 |
