Home > Enterprise >  get value inside object using parent key value
get value inside object using parent key value

Time:04-06

Is there any way to get a key-value from an objects 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;

CodePudding user response:

You cannot reference an Object parent that way.
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 this to the created child item parent property

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);

CodePudding user response:

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.

  • Related