0

I'm not sure why i can't access the allSubIABs array inside forEach. I can access the string newCheckState fine.

const newIABs = { ...this.state.iabs }
let allSubIABs = []
let newCheckState = 'asdasdasd'

console.log(typeof allSubIABs, allSubIABs)
Object.keys(newIABs).forEach(firstLevelIABCode => {
  console.log(newCheckState)
  console.log(typeof allSubIABs, allSubIABs)
  let allSubIABs = allSubIABs.concat(newIABs[firstLevelIABCode].children)
})

Output:

object []
asdasdasd
undefined undefined
Uncaught TypeError: Cannot read property 'concat' of undefined
2
  • What do you get from console.log( newIABS ) or console.log( Object.keys( newIABS ) )? I'm asking only because I've never seen the spread operator used to create an Object, only to populate an Array. Commented Nov 13, 2017 at 16:36
  • I'm actually going to mutate it later on in the code, thanks all for answering this dumb question I had lol. Commented Nov 13, 2017 at 16:49

2 Answers 2

3

Your problem is that the let declaration in the callback hides the outer allSubIABs declaration. Just get rid of that let.

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

1 Comment

Worth explaining what's happening here. I.e., the fact that, even though allSubIABs is referenced in the 2nd console.log within the forEach callback, it's re-declared in the line below that. JavaScript will hoist the declaration to the top of the scope, which effectively "resets" the value of that variable.
1

Your let allSubIABs declaration declares a new variable whose default value is undefined, and this new variable shadows access to the outer allSubIABs with the same name.

You can see how hoisting affects your function. This code is equivalent to your own:

Object.keys(newIABs).forEach(firstLevelIABCode => {
  let allSubIABs;

  console.log(newCheckState)
  console.log(typeof allSubIABs, allSubIABs)
  allSubIABs = allSubIABs.concat(newIABs[firstLevelIABCode].children)
})

As you can see, variable declarations happen first (this is what "hoisting" means) and newly-declared variables hold the value undefined until assigned a value.

Consider analogously var a = a.foo; which produces the error Cannot read property 'foo' of undefined because a does exists as a variable, but it has never been given a value.

Since you actually want to access the outer allSubIABs variable, do not declare a new variable with let. This will cause allSubIABs variable tokens to refer to the nearest outer-scope variable of that name, which is what you want.

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.