Probably every Titanium programmer already had this specific problem: Adding an event listener in a for loop and referencing the counting variable inside the listener results in unexpected behavior.

The code snippet above creates a TableView and populates it with TableViewRows having a click event. One would expect that clicking the first row alerts ‘0’, the second ‘1’ and so on.

Instead, each row alerts ‘9’. Why?

The reason is fairly logical. At the loop’s beginning, the variable i gets instantiated. Every TableViewRow event listener alerting the i references to the same, already instantiated variable. Now, later when the TableViewRow gets actually clicked, the loop is already finished and i set to 9.

How can the problem be solved? Look at the following snippet, improved lines are highlighted.

Exactly three aspects changed

  • The event listener function now has a value parameter
  • The alert is inside another function and references value instead of i
  • At the end, the event listener gets called passing the current as the value parameter

By putting the alert inside a new function inside the event listener function, a closure is created. Closures can access the variables of their outer function, in this case the value variable.

Directly after creating the event listener, the function gets called with i as the value parameter. As the closure uses value instead of i, and the function gets immediately called after creation, a new value variable gets instantiated for each TableViewRow, holding the current i value respectively.

This finally leads to the expected behavior: TableViewRow 1 alerts ‘0’, TableViewRow 2 alerts ‘1’ and so on.

Leave a Reply

Your email address will not be published. Required fields are marked *