Object: For In Loop

Tell us what’s happening:

I have checked my code thoroughly, and I expect that it would run. Unfortunately, all my tests are not passing. What could be wrong?

Your code so far


function countOnline(usersObj) {
// change code below this line
let number = 0;
for (users in usersObj){
  if( usersObj.users.online === true){
    number++ ;
  }
}
return number;
// change code above this line
}

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36 OPR/65.0.3467.78.

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

You shouldn’t use userObj inside your for loop. Instead just use users variable.
Change your if statement to this if( users.online === true){ might be help.
can’t make sure because i cant open the challenge link

Thank you David.
Tried your suggestion, but unfortunately, it didn’t work.

Hi.
The problem here is that the for in loop doesn’t really give a reference to the elements of an object, but only the names of the keys as strings. So one would access the nested objects by

for (userName in usersObj){
  if( usersObj[userName].online ){
    number++ ;
  }
}

Thanks Wutzig.
Tried your suggestion, that didn’t work either. I’ll keep trying.

@olucheye, the suggestion given by @wutzig above should work, just don’t forget to add the let statement. thus your edit to the for…in statement should look something like this:

for (let users in usersObj){
  if(usersObj[users].online == true){
    number++ ;
  }
}

Hope that helps!

You have to declare the users in the for...in loop and the test expects that you are using let (does not pass using const).

for (let users in usersObj)

1 Like

Thank you. Apparently, the let keyword was what was missing all of this while.
A terrible oversight on my part.

Quick question though, why does calling the property this way, not work ?

if(usersObj.users.online == true

I was thinking,

usersObj[users].online == true
is same as
usersObj.users.online == true

Thank you Lasjorg.
It was an oversight on my part. I have a question above. Do you have any idea why that is?

users is not a property on the usersObj object.

As said, the variable in the for…in loop is assigned the property as a String. It is not the actual Identifier. To use the string you have to use bracket notation.

const userObj = {
  Alan: {
    online: false
  },
  Jeff: {
    online: true
  },
  Sarah: {
    online: false
  }
};

for (const user in userObj) {
  if (userObj.hasOwnProperty(user)) {
    console.log(typeof user);
    // string, string, string
  }
}


console.log(userObj.Alan);
// { online: false }

console.log(userObj["Alan"]);
// { online: false }
1 Like

That is a really good question. I think it is because, typically using dot notation to access properties implies the value after the dot is indeed the name of the property and not a variable. In this case the word - users - is a variable and not the actual name of the property, thus passing it into the square brackets allows the script to replace the value of users with the name of properties.

usersObj[users].online will replace the users part with the string inside the - let users
usersObj.users.online is the same as saying inside the usersObj their is a property called users that is not the variable users.

Does that make sense?

In summary, the square bracket passes the variable content as the property name, whilst the dot notation one looks for a property called users.

1 Like