0

I am trying to use a dynamically updated accessor for a javascript array inside of an object literal constructor. Both data and index variables are in the same functional scope.

var data = [];
var index = 0;

dateKeys.forEach(element=>{

data.push({"date":element,[otherKeys[0]]:currentAccount[index]["2017_Q1"],[otherKeys[1]]:0,[otherKeys[2]]:0,[otherKeys[3]]:0,[otherKeys[4]]:0,[otherKeys[5]]:0})
index = index +1;

})

The code above produces the following error message: TypeError: undefined is not an object (evaluating 'currentAccount[index]["2017_Q1"]')

Yet when I try:

 dateKeys.forEach(element=>{
 var index = 0;
 data.push({"date":element,[otherKeys[0]]:currentAccount[index]  ["2017_Q1"],[otherKeys[1]]:0,[otherKeys[2]]:0,[otherKeys[3]]:0,[otherKeys[4]]:0,[otherKeys[5]]:0})
index = index +1;

})

I get the correct data for index 0 but it does not update. Why does the scoping seem to make a difference here to the ability to use a variable name in place of a number in the square brackets? I have tried using let, to see if it was a binding issue, but that makes no difference. Is there a solution using vanilla javascript?

1
  • 3
    This example is incomplete--it's not clear what currentAccount, otherKeys or dateKeys are. See minimal reproducible example for help on how to write an answerable question. Commented Apr 6, 2019 at 20:25

3 Answers 3

1

This is because you are declaring and initializing index variable each time when forEach callback is called.

For example if dateKeys has 5 items, then element => ... will be called 5 times and each time creating a new variable index and setting it's value 0.

In second case you are never accessing currentAccount with index value 1.

You are getting this error because dataKeys, has more entries than currentAccount.

Sign up to request clarification or add additional context in comments.

Comments

1

var is function-scoped, which means your index gets hoisted to the top and out of the loop-block. Each time you loop through dataKeys, it will always be referencing the same hoisted index.

Use let to declare index inside forEach, or simply expose the index argument from forEach:

dateKeys.forEach((element, index) => {
  // use index here
})

Comments

1

The problem is that you are declaring index every single time the loop runs - the code inside the function will be executed every time. You need to use the built-in forEach index parameter (the second one):

dateKeys.forEach((element, index) => {
    data.push({"date":element,[otherKeys[0]]:currentAccount[index]  ["2017_Q1"],[otherKeys[1]]:0,[otherKeys[2]]:0,[otherKeys[3]]:0,[otherKeys[4]]:0,[otherKeys[5]]:0});
});

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.