Aditya Lamba
Aditya Lamba

Reputation: 29

Why obj is not iterable

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));

Upvotes: 0

Views: 389

Answers (2)

Taki
Taki

Reputation: 17654

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})
}

Upvotes: 0

adiga
adiga

Reputation: 35222

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)

Upvotes: 4

Related Questions