Cannot read property 'online' of undefined

Viewed 114

Here is my code I'm trying to count how many online users we have with the countOnline function.

I'm getting the error "Cannot read property 'online' of undefined";

function countOnline(usersObj) {
  let amount=0;

  for(let user in usersObj){
    if(usersObj.user.online){
      amount++;
    }
  }

  return amount;
}

let a = countOnline({
  Alan: { online: false },
  Jeff: { online: true },
  Sarah: { online: false }
});

console.log(a);

3 Answers

You are trying to access userObj.user.online, while it should be userObj[user].online:

function countOnline(users) {

  let amount = 0;
  
  for (const user in users) {
    if (users[user].online) {
      amount++;
    }
  }

  return amount;
}

const a = countOnline({
  Alan: {
    online: false
  },
  Jeff: {
    online: true
  },
  Sarah: {
    online: false
  }
});

console.log(a);

function countOnline(usersObj) {
  
  let amount=0;
  for(let user in usersObj){
    if(usersObj.online){
      amount++;
    }
      
  }
  return amount;
  
}
let a = countOnline({ Alan: { online: false }, Jeff: { online: true }, Sarah: { online: false } });

console.log(a);

You are trying to get the property user where it should be a user name instead. Use [user] instead of .user. while iterating object keys.

See the fixed snippet below:

function countOnline(usersObj) {
   let amount=0;
   for(let user in usersObj){
     if(usersObj[user].online){ // <-- see, I placed user in [ ]
       amount++;
     }
   }
   return amount; 
}
    
let a = countOnline({
   Alan: { online: false },
   Jeff: { online: true },
   Sarah: { online: false } 
});
    
console.log(a);

Alternative solution

You may iterate object values in even more clean and readable way, for example with usage of Object.values() method, which will return you an array of all users in your case, so you need just to reduce it.

function countOnline(usersObj) {
   return Object.values(usersObj).reduce((total, user) => user.online ? total + 1 : total, 0)
}
    
let a = countOnline({
   Alan: { online: false },
   Jeff: { online: true },
   Sarah: { online: false } 
});
    
console.log(a);

And even shorter, but less performant:

let usersObj = {
   Alan: { online: false },
   Jeff: { online: true },
   Sarah: { online: false } 
};

let onlineCount = Object.values(usersObj).filter(u => u.online).length;

console.log(onlineCount);

You used for in. dictionary is not iterable like arrays. you need key, value. Just try this.

function countOnline(usersObj) {
  let amount=0;

for (const [key, value] of Object.entries(usersObj)) {
    if(value.online){
        amount++;
    }
}

  return amount;
}

let a = countOnline({
  Alan: { online: false },
  Jeff: { online: true },
  Sarah: { online: false }
});

console.log(a);

If you want to use for in loop in your code do like this

let a = countOnline([
      {Alan: { online: false }},
      {Jeff: { online: true }},
      {Sarah: { online: false }}
    ]);
Related