-1

I'm trying to return the number of users that are online as determined by this JS object. However, my counter for users that are currently online never gets incremented.

I use the for-in loop to iterate through the JS object, and then I increment the 'usersOnline' variable if the specific user's 'online' property is set to true.

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) {
  let usersOnline = 0;

  for (let user in obj) {
    if (user.online === true)
      usersOnline++;
  }

  return usersOnline;
}

console.log(countOnline(users));

usersOnline should be incremented twice so that it is equal to 2. But it stays set at 0. This problem is part of a coding challenge on freeCodeCamp.com I'm more interested in why this specific code won't work versus how to use JS objects in general.

Herohtar
  • 5,347
  • 4
  • 31
  • 41
  • 1
    A `for ... in` loop iterates through the **keys** of the object, not the values. – Pointy Jun 24 '19 at 23:41
  • Small note: it's a bad practice to check `if (something === true)`. Instead, just check `if (something)`. – frodo2975 Jun 24 '19 at 23:47
  • 2
    I understand that this probably isn't the best practice for any real tasks, but I'm more interested in learning what about this specific code isn't working, I don't really need info on how to use JS objects in general. – thejacobhardman Jun 24 '19 at 23:52
  • That is easily discovered by looking at the documentation for [`for...in` loops](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in) (or even just `console.log(user)` to check its value), where you will see that it loops through the property *names*, not the property values. – Herohtar Jun 24 '19 at 23:56
  • The for in loop was actually working perfectly. I just needed to go a level deeper when checking the object's values. – thejacobhardman Jun 25 '19 at 00:18

1 Answers1

0

One solution would be to reduce() the values() of the users object to obtain a total number of users that are online:

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

const onlineCount = Object.values(users).reduce((total, user) => {
  /* If user is online, add 1 to the total, otherwise add 0 */
  return total + (user.online ? 1 : 0);
}, 0)

console.log(onlineCount)

The reduce() works by starting with an initial value of 0, and iterating all user values returned by Object.values(), adding a 1 or 0 to the total in order to obtain the total count of online users.

Dacre Denny
  • 29,664
  • 5
  • 45
  • 65