0

While compiling this code I am getting an error that obj is not iterable. Why? I have to check how many users are online

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 num =0;
  for(let user of obj){
    if(user['online']==true){
      num++;
    }
  }
  return num;
}

console.log(countOnline(users));

2 Answers 2

4

Because you are using for...of instead of for...in.

for...of is used for looping over iterable objects while for...in iterates over the enumerable properties of an object. For for...of to work, the object must implement the @@iterator method (Array, string, Set etc)

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 num = 0;
  for (let user in obj) {
    if (obj[user]['online'] == true) {
      num++;
    }
  }
  return num;
}

console.log(countOnline(users));

In for...in, the user variable will represent key of the object like Alan. So, to get the value of the property, you need to do use obj[user] (eg: obj["Alan"]). So, the condition will be changed to:

if (obj[user]['online'] == true)
Sign up to request clarification or add additional context in comments.

3 Comments

But even after using in rather than on num is returning to be 0.
@AdityaLamba you also need to change the condition to obj[user]['online']
@AdityaLamba I have added the explanation belwo snippet. user will be the key name like "Alan", "Jeff". There is no online property in a string. obj[user] will get the value for the "Alan" key
0

Objects don't have the @@iterator symbol by default , to use for..of you'll need to add it to the object :

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

users[Symbol.iterator] = function*() {
  for (value of Object.values(this)) {
    yield value;
  }
};

for (let user of users) {
  console.log(user)
}

Or use for..of with Object.entries ( or Object.values )

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

for (let [key, value] of Object.entries(users)) {
  console.log('key :', key, 'value : ', value)
}

console.log('***********');

for (let user of Object.values(users)) {
  console.log({user})
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.