1

I have a library the needs an array of buttons in order to produce a UI, this array has objects with a Text to show and a callback to call when the button is pressed. For this example as callback I'm using a console.log to show a value that gets randomly generated during the population of the array:

var buttons = [];
for(var x = 0; x < 3; x++) {
  var value = Math.random()*10;
  buttons.push({ 
    text: "Foo", 
    onTap: function() { console.log("Im a button and my value is", value) } })
}

As you can see right away since onTap gets called later on when the user taps the button, the value that console.log shows is the last one, meaning that all buttons will show the same value. I can modify the library to include some kind of meta field in the object where I can store the values and then retrieve them from the onTap function. But I prefer not to touch the library, is there a better way to tackle this?

DomingoSL
  • 14,920
  • 24
  • 99
  • 173
  • you should be able to achieve this by putting `button.push{...}` in IIFE as in [plnkr](http://plnkr.co/edit/71HksPY6Pp4gLMihCw9Z?p=preview) – Anant Aug 22 '18 at 11:21

1 Answers1

0

for is not scoped, so value is the last value always, you can scope the value by warping inside a function like below

var buttons = [];
for(var x = 0; x < 3; x++) {
 (function() {
  var value = Math.random()*10;
  buttons.push({ 
    text: "Foo", 
    onTap: function() { console.log("Im a button and my value is", value) } })
 })();
}

For your reference : https://scotch.io/tutorials/understanding-scope-in-javascript

Or just use let instead of var

var buttons = [];
for(var x = 0; x < 3; x++) {
  let value = Math.random()*10;
  buttons.push({ 
    text: "Foo", 
    onTap: function() { console.log("Im a button and my value is", value) } })
}
Shanaka Rusith
  • 421
  • 1
  • 4
  • 19