RamAlx
RamAlx

Reputation: 7334

ESLint doesn't allow for in

I have an object

currentValues= {hey:1212, git:1212, nmo:12121}

and I use for in like this:

for (const key in currentValues) {
    if (Object.prototype.hasOwnProperty.call(currentValues, key)) {
        yield put(setCurrentValue(key, currentValues[key]));
    }
}

ESLint shows me an error which is saying:

ESLint: for..in loops iterate over the entire prototype chain, which is virtually never what you want. Use Object.{keys,values,entries}, and iterate over the resulting array. (no-restricted-syntax

How should I edit my code?

Upvotes: 66

Views: 83432

Answers (8)

Parth shah
Parth shah

Reputation: 41

let animal = {
  eats: "Eating",
};
let rabbit = {
  jumps: "Jumping",
};

rabbit.__proto__ = animal;

for (const rabbitProps in rabbit) {
  // This will print both eats and jumps properties because they're part of
  // prototype chain
  console.log("rabbitProps: ", rabbitProps);
}

// This prints only jumps as Object.keys shows only the keys of object
console.log(Object.keys(rabbit));

Checking out the above code you can see that when using for...in loop[ it will show all the properties that are part of object as well as properties set in the prototype chain of the object and so eslint suggests to use Object.keys or value or entries, as they do not look into prototype chain instead they just look at your object.

Upvotes: 4

OnlyZero
OnlyZero

Reputation: 491

I would do it by refactoring, in the following ways.

const currentValues = { hey: 1212, git: 1212, nmo: 12121 };

Object.keys(currentValues).forEach((e) => console.log(`${e} : ${currentValues[e]}`));

Results:

hey : 1212 git : 1212 nmo : 12121

Object.values(currentValues).forEach((e) => console.log(`Values: ${e}`));

Results:

(2)Values: 1212 Values: 12121

Object.entries(currentValues).forEach((e) => console.log(`${e[0]} : ${e[1]}`));

Results:

hey : 1212 git : 1212 nmo : 12121

Upvotes: 6

Daher
Daher

Reputation: 1441

try this instead:

Object.keys(currentValues).map(key => (yield put(setCurrentValue(key, currentValues[key]))));

Upvotes: 2

Andres Felipe
Andres Felipe

Reputation: 4330

I know it is similar to the above, but here is a full example:

const data = res.data;
const keys = Object.keys(data);
const values = Object.values(data);

for (let i = 0; i <= keys.length; i += 1) {
  if (Object.prototype.hasOwnProperty.call(values, i)) {
     this.rows.push({
        name: values[i].name,
        email: values[i].email,
        address: values[i].address,
        phone: values[i].phone,
        role: values[i].role,
  });
 }
}

Upvotes: 3

RamAlx
RamAlx

Reputation: 7334

I used the following:

const keys = Object.keys(currentValues);
const values = Object.values(currentValues);
for (let i = 0; i < keys.length; i += 1) {
    yield put(setCurrentValue(keys[i], values[i]));
}

This is correct and without ESLint errors.

Upvotes: 14

rishipuri
rishipuri

Reputation: 1528

It says,

Use Object.{keys,values,entries}, and iterate over the resulting array.

So you could do something like this to get the object keys as an array and then loop through the keys to make necessary changes.

currentValues= {hey:1212, git:1212, nmo:12121}

Object.keys(currentValues).forEach(function(key) {
  yield put(setCurrentValue(key, currentValues[key]));
})

Upvotes: 88

quirimmo
quirimmo

Reputation: 9988

You can get the array of all your values inside your object just doing

var myValuesInArray = Object.values(currentValues);

Upvotes: 4

jakow
jakow

Reputation: 21

Using for...in will iterate over all properties including those from Object prototype. I am not sure why you are doing Object.prototype.hasOwnProperty.call(currentValues, key) instead of just: currentValues.hasOwnProperty(key). I think this should make ESLint aware that you are filtering for own properties only.

However, I suggest using for (const key of Object.keys()), which is more semantic.

Upvotes: 0

Related Questions