Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 757
Yazan W Yusuf Avatar asked Sep 10 '17 21:09

Yazan W Yusuf


2 Answers

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);
}
like image 61
Rory McCrossan Avatar answered Nov 05 '22 04:11

Rory McCrossan


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);
  });
});
like image 2
Redu Avatar answered Nov 05 '22 06:11

Redu