0

Why do I always get the last value assigned to the variable even though I already enclosed it in a function?

When the event mouse up is triggered and getGoogleFiles is called, the last value assigned to resourceId is called. I don't get it.

for ( var i in arrayObj) {
 var resourceId = arrayObj[i].ResourceId;
 entity_list.onmouseup = function(event) {
    parent.changeButtonState(this, event);
    (function(resourceId) {
        getGoogleFiles(resourceId);
    })(resourceId);
 }
}

Note: This is different to other JavaScript questions because the onmouseup is not triggered

I followed the creating of another function mentioned here: JavaScript closure inside loops – simple practical example

for ( var i in arrayObj) {
 entity_list.onmouseup = function(event) {
  parent.changeButtonState(this, event);
  testing(arrayObj[i].ResourceId);
 }
}

function testing(index){
   return function() { getGoogleFiles(index); };
}

But when the element of "entity_list" is triggered, nothing happens. I can't use let because the specific browser that I'm using returns a SyntaxError

SyntaxError: Block-scoped declarations (let, const, function, class) not yet supported outside strict mode

Thank you!

mengmeng
  • 1,266
  • 2
  • 22
  • 46

2 Answers2

1

You need to use testing() to create the listener function, not something you call inside it.

for (var i in arrayObj) {
  entity_list.onmouseup = testing(arrayObj[i].ResourceId, parent);
}

function testing(index, parent) {
  return function(event) {
    parent.changeButtonState(this, event);
    getGoogleFiles(index);
  };
}

But you wouldn't have to go through any of this if you use forEach() instead of a for loop, since it creates a new scope for obj in each iteration.

arrayObj.forEach(function(obj) {
  entity_list.onmouseup = function(event) {
    parent.changeButtonState(this, event);
    testing(obj.ResourceId);
  }
});
Barmar
  • 741,623
  • 53
  • 500
  • 612
0

You can't use a var scoped variable here. But you could assign the resourceId to a data attribute on the relative html element, so you can read it when the event fires.

var arrayObj = [{ResourceId: "test1"}, {ResourceId: "test2"}, {ResourceId: "test3"}];

var entity_list = document.getElementsByClassName("entity_list");

for ( var i in arrayObj) {
 entity_list[i].dataset.resourceId = arrayObj[i].ResourceId;
 entity_list[i].onmouseup = function(event) {
    getGoogleFiles(this.dataset.resourceId);
 }
}

function getGoogleFiles(resourceId) {
  console.log(resourceId);
}
<span class="entity_list">entity list (item 1)</span>
<span class="entity_list">entity list (item 2)</span>
<span class="entity_list">entity list (item 3)</span>
Alessandro
  • 4,382
  • 8
  • 36
  • 70