Iterate Through the Keys of an Object with a for...in Statement - Selector Issue

Tell us what’s happening:
I already found the solution to this problem, but I was wondering if someone could clarify why the selector I used below does not work:

My selector (causes error “Cannot read property ‘online’ of undefined”):

if (obj.user.online == true) {
count++;
}

Solution (correct selector):

if (obj[user].online == true) {
count++;
}

Can someone please explain why you need to use bracket notation (obj[user].online) instead of dot notation (obj.user.online)?

Your code so far


let users = {
  Alan: {
    age: 27,
    online: false
  },
  Jeff: {
    age: 32,
    online: true
  },
  Sarah: {
    age: 48,
    online: false
  },
  Ryan: {
    age: 19,
    online: true
  }
};

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

console.log(countOnline(users));

Your browser information:

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

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

You might want to review the lessons on dot notation and bracket notation.
obj.user will work if you have

let obj = {
user: 'whatever'
...
}

And will not work here

let user = 'joe'
obj = {
joe: 'whatever'
...
}

Because I am assuming you defined user as a variable in the for in loop (i.e. for (let user in users)). You cannot use dot notation with variables, you have to use brackets because the brackets actually evaluate/unpack the values behind the variables. The dot notation just looks for an identifier of the same name and if it doesn’t see it, it returns undefined, or creates it if you want it to. Example for the bracket notation, if you have

let user = "John"
let obj = {};

obj.user = "Doe"
/// this will not make the object {John : Doe}, it will make it {user : Doe}

Thanks for the explanations!