Abozanona
Abozanona

Reputation: 2295

How to pass a specific array element for a callback of event

I have an array of objects that holds each "actionButton" id, selector and callback

var actionButtons = [
    {
        id:"0",
        selector:"._55ln._qhr",
        callback: undefined
    },
    {
        id:"1",
        selector:"._22aq._jhr",
        callback: undefined
    },
    .
    .
    .
];

What I'm trying to do is calling a function with a specific parameter from the array(the id) every time a selector is clicked.

for(var i=0;i<actionButtons.length;i++){
    $(document).on('click', actionButtons[i].selector, function() {
        makeAction(actionButtons[i].id);
        if (actionButtons[i].callback)
            actionButtons[i].callback(this);
    });
}

But this code is not working; it looks like every time the callback function is called the value of i is equal to the array size.

How can I solve this problem;ie. to make the value of the variable i become different for each callback.

Upvotes: 5

Views: 629

Answers (3)

Redu
Redu

Reputation: 26191

In order not to fall into closure ambush you may always use array methods like

actionButtons.forEach(function(ab) {
  $(document).on('click', ab.selector, function() {
    makeAction(ab.id);
    ab.callback && ab.callback(this);
  });
});

Upvotes: 2

gaetanoM
gaetanoM

Reputation: 42054

You can use let:

The let statement declares a block scope local variable, optionally initializing it to a value.

Let will assure you the closure.

for(let i=0;i<actionButtons.length;i++){
   $(document).on('click', actionButtons[i].selector, function() {
       makeAction(actionButtons[i].id);
       if (actionButtons[i].callback)
         actionButtons[i].callback(this);
     });
}

Upvotes: 0

Rory McCrossan
Rory McCrossan

Reputation: 337646

The issue is because the i variable is being incremented in the loop. This means that when the first event handler actually runs after the loop completes, i is the maximum value, not 0.

To fix this you can use a closure:

for(var i = 0; i < actionButtons.length; i++) {
  (function(i) {
    $(document).on('click', actionButtons[i].selector, function() {
      makeAction(actionButtons[i].id);
      if (actionButtons[i].callback)
        actionButtons[i].callback(this);
    });
  })(i);
}

Upvotes: 5

Related Questions