1

Basically I am testing ES6 and wanted to try and return an object of objects from an array of objects, each object in the array has an id and a parent, the id will be the name of the property held within the parent. Simple enough, here is my code:

//an array of objects

let animals = [{
            id: "animal",
            parent: null
}, {
            id: "dog",
            parent: "animal"
}, {
            id: "cat",
            parent: "animal"
}, {
            id: "fish",
            parent: "animal"
}, {
            id: "labrador",
            parent: "dog"
}, {
            id: "cocker spaniel",
            parent: "dog"
}, {
            id: "bass",
            parent: "fish"
}, {
            id: "tuna",
            parent: "fish"
}, {
            id: "house cat",
            parent: "cat"
}, {
            id: "outdoor cat",
            parent: "cat"
}, {
            id: "human",
            parent: "animal"
}, {
            id: "man",
            parent: "human"
}, {
            id: "woman",
            parent: "human"
}];

//a recursive function to build our object of objects tree

let makeTreeOfCategories = (categories, parent) => {
            let parentNode = {};
            categories
                        .filter(category => category.parent === parent)
                        .forEach(category => parentNode[category.id] =
                                    makeTreeOfCategories(categories, category.id));
            return parentNode;
};

console.log(JSON.stringify(makeTreeOfTrees(animals, null), null, 2));

This code will return:

{
    "animal": {
        "dog": {
            "labrador": {},
            "cocker spaniel": {}
        },
        "cat": {
            "house cat": {},
            "outdoor cat": {}
        },
        "fish": {
            "bass": {},
            "tuna": {}
        },
        "human": {
            "man": {},
            "woman": {}
        }
    }
}

Now, if we run the following:

//call our object and store in a variable

let obj = makeTreeOfCategories(animals, null);

//loop through the object and alert each child item and its children

for (var key in obj) {
            var val = obj[key];
            alert("Key: " + key + " value:" + val);
}

it alerts one time saying "Key: animal value: [Object object]" but what I don't understand is why, I would expect it to return with "key: animal value: dog" then "key: animal value: cat" and so on.

you know, basically allowing me to loop through each object inside the object of objects and alert its properties and their values.

Also, if you could tell me this also, how would I access something like:

{}.animal.dog.labrador 

If I was looking for something specific like if Labrador had a property called name for example.

I hope that makes sense, I think I am just confusing myself if anything just now but I hope I made clear what I have tried and what I would like to happen.

Cheers, SD

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • possible duplicate of [Converting an object to a string](http://stackoverflow.com/q/5612787/1048572) or [Why `[object Object]` mentions “object” twice?](http://stackoverflow.com/q/29847665/1048572) – Bergi Nov 03 '15 at 12:25

2 Answers2

0

You loop will only return the properties of the parent object - animals. You'll need to recursively call it on each child element to get all alerts. Additionally, the reason you are seeing [Object object] is because you are trying to convert {} to a string. In your tree, the keys are the only part you can print with no special toString().

function recursiveAlert(node) {
    for (var key in node) {
        var val = node[key]

        alert("Key: " + key);

        recursiveAlert(val);
    }
}

On the nature of your [Object object], if all you want is the immediate children, you can write a function to get them as a string for you.

function getChildren(node) {
    // get all properties as an array, then convert to a string
    return Object.keys(node).toString();
}

function recursiveAlert(node) {
    for (var key in node) {
        var val = node[key]

        alert("Key: " + key + ", Val: " + getChildren(val));

        recursiveAlert(val);
    }
}

Finally, how to can check for the existence of a specific property. if you have an object

var tree = {id: 2};

and you try to access a property on it which doesn't exist, you will get undefined, a falsy value.

tree.dog;
// => undefined

This means that you can check for the existence of properties using if statements. However, you can only go one layer deep, that is.

tree.dog.lab;
// => TypeError

But this is okay.

if (tree.dog) {
  if (tree.dog.lab) {
     // do something
  }
}
Jonah Williams
  • 20,499
  • 6
  • 65
  • 53
0

You Are getting value: [Object object]" is correct this is how for in work in JavaScript
for in iterate key value on a object or a array for example if structure of your object is something like this

var obj = {"animal":"dog","Bird":"peacock"}

for (var key in obj) {
      alert("Key: " + key + " value:" + val);
}     

Output

Key: animal value:dog
Key: Bird value:peacock

But in Your case

"animal" is a upper key of a nested object which hold objects inside it,that's why your loop run only for one Time and return objects

"animal" actually hold following value

 "dog": {
            "labrador": {},
            "cocker spaniel": {}
        },
        "cat": {
            "house cat": {},
            "outdoor cat": {}
        },
        "fish": {
            "bass": {},
            "tuna": {}
        },
        "human": {
            "man": {},
            "woman": {}
        }

it's an object that's why [Object object] shown in alert.

you can see keys of your inner object by this way;

for (var key in obj) {
            var val = obj[key];
            alert("Key: " + key + " value:" + Object.keys(val));
}

output :

Key: animal value:dog,cat,fish,human

For your second question how to get object property value by using "." use

console.log(obj.animal.dog.labrador)

it show Object {}

and if you want to read keys use

console.log(Object.keys(obj.animal.dog)) it will show

["labrador", "cocker spaniel"]
Shailendra Sharma
  • 6,976
  • 2
  • 28
  • 48