I did my best not to post a duplicate topic by doing a full search on Stack including some of the suggested Similar Questions on right side panel of this page but could not find a decent post that could help me. Here is a partial list of my search queries:
https://stackoverflow.com/search?q=javascript+access+deep+object+literals (first search query)
https://stackoverflow.com/search?q=javascript+access+nested+object+literals (second search query)
javascript access chain with nested object literals
Accessing Properties of nested Javascript literals in a for loop ) Javascript - Assigning multiple variables to object properties using curly braces in variable declaration
And now on to my question:
I have a collection of nested definition objects inside an array that I am having difficulty accessing so that I could build a list of anchors from it for my nav bar. I created a function to hoist the array so I can place it anywhere in my code but that is not a problem (I don't think?).
function hoistNav() {
const nav = [];
nav[0] = {text: 'HOME', att: {href: 'home.html', class: 'nav', id: 'zero'}};
nav[1] = {text: 'POSTS', att: {href: 'posts.html', class: 'nav', id: 'one'}};
nav[2] = {text: 'CONTACT', att: {href: 'con.html', class: 'nav', id: 'two'}};
return nav;
}
I would like to create links by accessing all attributes inside obj.att like this:
function createAnchor(obj) {
let el = document.createElement('a');
el.textContent = obj.text;
for(let key in obj.att){
el.setAttribute(key, [key]);
}
return el;
}
I also need to create a list of links with another function but that will be ignored for simplicity. A typical sample run should be like this:
let nav = hoistNav();// returns an array of nested objects
let obj = nav[0];// a sample run
createAnchor(obj);// should return: <a href="home.html" class="nav" id="zero">HOME</a>
As it is now the above code isn't working for me. What am I doing wrong? Also is there a best practices way of listing and destructuring all properties including nested ones for objects similar to this?
The line
el.setAttribute(key, [key]);
tries to set the attribute to an array containing the key as its only entry (and thus will set href
to "href"
since the array will get coerced to string). You probably meant
el.setAttribute(key, obj.att[key]);
// ------------------^^^^^^^
Live Example:
function hoistNav() {
const nav = [];
nav[0] = {text: 'HOME', att: {href: 'home.html', class: 'nav', id: 'zero'}};
nav[1] = {text: 'POSTS', att: {href: 'posts.html', class: 'nav', id: 'one'}};
nav[2] = {text: 'CONTACT', att: {href: 'con.html', class: 'nav', id: 'two'}};
return nav;
}
function createAnchor(obj) {
let el = document.createElement('a');
el.textContent = obj.text;
for(let key in obj.att){
el.setAttribute(key, obj.att[key]);
}
return el;
}
let nav = hoistNav();
let obj = nav[0];
let anchor = createAnchor(obj);
document.body.appendChild(anchor);
console.log(anchor.outerHTML);
Side note: Not quite sure what hoistNav
is for, you could just make nav
global to your code (but not actually global):
"use strict"; // Strict mode to ensure correct handling of function decl in block
// Scoping block to avoid creating globals
{
// Note use of literal notation
const nav = [
{text: 'HOME', att: {href: 'home.html', class: 'nav', id: 'zero'}},
{text: 'POSTS', att: {href: 'posts.html', class: 'nav', id: 'one'}},
{text: 'CONTACT', att: {href: 'con.html', class: 'nav', id: 'two'}}
];
function createAnchor(obj) {
let el = document.createElement('a');
el.textContent = obj.text;
for (let key in obj.att) {
el.setAttribute(key, obj.att[key]);
}
return el;
}
// Sample run
let obj = nav[0];
let anchor = createAnchor(obj);
document.body.appendChild(anchor);
console.log(anchor.outerHTML);
}