Click here to Skip to main content
15,881,882 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I'm trying to change the value in an object for use later. How come values aren't retained using this method?

I have the following code:
JavaScript
window.myobj = {
    a: {_a: '_a here', _b: '_b here', _c: ''},
    b: {_a: '_a here', _b: '_b here', _c: ''},
    c: {_a: '_a here', _b: '_b here', _c: ''}
    //etc.
}

myobj['a']._c = 'test';
alert(myobj['a']._c); // not test!
This works fine for the predefined values, but not dynamically-set ones.

EDIT:

I've narrowed it down to a loop issue - the key is always the last one in the array.
JavaScript
window.keys = Object.keys(servers);

for(var i = 0; i < keys.length; i++)
{
        var key = keys[i];
        var xhr = new XMLHttpRequest();

        xhr.addEventListener('load', function()
        {
                alert(key); // this is the issue due to this happening after the loop is finished
                myobj[key]._c = this.responseText;
        });

        xhr.open('GET', 'test.php?s=' + myobj[key]._b);
        xhr.send();
}


What I have tried:

Setting the value directly, using ['_c'] and setting myobj['a'] to a new object entirely.
Posted
Updated 21-Jan-18 3:29am
v3
Comments
Thomas Daniels 21-Jan-18 9:01am    
I tried to run this and it's alerting "test", as expected and desired.
[no name] 21-Jan-18 9:07am    
I've edited the question

1 solution

The problem "the key is always the last one in the array" is indeed happening because the 'load' events only get fired after the loop is over, so key is indeed equal to the last key at the time you call alert(key). This problem can be solved by replacing your addEventListener call by this:
JavaScript
xhr.addEventListener('load', (function(k) {
  return function() {
    alert(k);

    myobj[k]._c = this.responseText;
  };
})(key));
This looks a bit complicated, so let's break this piece of code down into its different parts.
JavaScript
(function(k) { ... })(key)
The above is a self-executing function. When the function executes itself, we pass key as the k parameter: k will be the key at the time that addEventListener got called and it will not be affected by changes to the key variable.

Inside the self-executing function, we return a new function. We need to do that because we do not want to run alert (and the other line) immediately: we want to have a function that we can pass to addEventListener so that it runs on the 'load' event. So we have to return the function that we want to get fired on the 'load' event:
JavaScript
return function() {
  alert(k);

  myobj[k]._c = this.responseText;
};
We use k here and not key, because we want to use the variable inside the self-executing function that doesn't get affected by key changes.
 
Share this answer
 
Comments
[no name] 24-Jan-18 11:31am    
Very useful. I've seen (something) used after function(){} several times but I've never known what it does. I ended up using a different solution, by passing the key to the php file and having it return the key along with the result from its processing. Thanks for the help anyway though, it's very insightful.
Thomas Daniels 24-Jan-18 11:32am    
You're welcome!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900