For...in digging deeper

I seem to be having a problem trying to dig a little deeper into the object being passed to the function. i.e. trying to access obj[a][‘other’]['good]

Is this a limitation of the for…in method?

I can access obj[a]['home] no problem but as soon as I try to go a level deeper:

obj[a].other.good or
obj[a][‘other’].good or
obj[a][‘other’][‘good’]

I get the console message:

“TypeError: obj[a].other is undefined”

My code so far


function countOnline(obj) {
// set up a variable to hold the count of true
let count = 0;
// iterate through each key of the object passed to the function
for (let a in obj) {
  if (obj[a]['online'] || obj[a]['home'] || obj[a]['other'].good === true) {
    count++;
  }    
} 
return count;  
}

console.log(countOnline({
Alan: {
  online: false,
  home: true,
  other: {
    good: true
  }
},
Jeff: {
  online: false
},
Sarah: {
  online: true
}
}
))

Any enlightenment would be greatly welcome :slight_smile:

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:73.0) Gecko/20100101 Firefox/73.0.

Challenge: Iterate Through the Keys of an Object with a for…in Statement

Link to the challenge:
https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-data-structures/iterate-through-the-keys-of-an-object-with-a-for...in-statement

Hi there,
OK, I think I got this.
Is it because the way you have it set up with the ‘||’ statements, it is expecting to see 2 levels of nested objects in each iteration that comes in to the ‘if’ statement and when it can’t see the 2nd nested object, it throws the error.
I adjusted the code to only take the first, nested, Alan object and it worked fine.
Give that a shot.

console.log(countOnline({
Alan: {
online: false,
home: true,
other: {
good: true
}
}
}
))

** Here is a reference I found: https://hackernoon.com/accessing-nested-objects-in-javascript-f02f1bd6387f

Ok, after spending much time on this, and trying to work out that link, and just starting from scratch again, I have still not solved this! :((
Keep getting strange results, like its a bad created object.
But it looks ok?
Any other ideas.
– I might be getting closer, lol

@ReallyWant2Learn I really thought you hit the nail on the head there! You are correct in that it works fine on the Alan object. That made me think, is it the fact that the other two nested objects don’t have the ‘other’ property with an object as a value? Easy to check! Just stick the ‘other’ property in the Jeff and Sarah objects. Well, here’s where it gets a bit wierd. I put the 'other property in the Jeff object first and the TypeError vanished. How strange, I hadn’t modified the Sarah object! However, if i then set Sarah.online to false, the error came back. That is until I added the ‘other’ property and it went away again.

So it’s definately something to do with the object being passed v’s the for…in method. Here’s what I have at the moment that works:

function countOnline(obj) {
// set up a variable to hold the count of true
let count = 0;
// iterate through each key of the object passed to the function
for (let a in obj) {
  if (obj[a]['online'] || obj[a]['home'] || obj[a]['other'].good === true) {
    count++;
  }    
} 
return count;  
}

console.log(countOnline({
Alan: {
  online: false,
  home: false,
  other: {
    good: false
  }
},
Jeff: {
  online: false,
  other: {
    good: false
  }
},
Sarah: {
  online: false,
  other: {
    good: false
  }
}
}
))

Question is now. Why isn’t it complaining about the ‘home’ property not being present in Jeff & Sarah?

The problem might be when you try to access a property from undefined.

Remember: When evaluating a series of conditions separated by the logic OR operator, ||, the whole expression resolves to true as soon as one of the conditions evaluates to true, and the remaining unevaluated expressions after that one are ignored.

So, when evaluating Alan, everything works fine, you get
if (false || true)

When evaluating Jeff, that’s when you get the Error
If you access obj[a]['home'], the obj[a] is defined, it is the nested Jeff object, but Jeff doesn’t own the property ["home"] so you get undefined. Also, Jeff doesn’t own the property ["other"] so you get undefined again. But then you try to access ["good"] from undefined.

The evaluation of Jeff goes like
if (false || undefined || "what am I trying to access? What is undefined? I dunno. Let me crash")
Remember that undefined is falsy, so the evaluation continues.

If you remove Jeff, the evaluation of Sarah is fine because you get
if (true)