views:

53

answers:

3

I have an object I'm trying to populate from another object (that is, iterate over a return object to produce an object with only selected values from the original). My code looks like this:

var collect = {};

function getHistoricalData(username){
$.getJSON("http://url/" + username + ".json?params",
            function(data){
                for (var i=0; i < data.length; i++) {
                    console.log(i);
                    collect = { i : {text : data[i].text}};
                    $("#wrap").append("<span>" + data[i].text + "</span><br />");

                };
                console.log(collect);
            }); 

}

So I'm using Firebug for debugging, and here's what I know:

  • The JSON object is intact
  • console.log(i); is showing the numbers 1-20 as expected
  • When I log the collect object at the end, it's structure is this: var collect = { i : {text : "the last iteration's text"}};

    So the incrementer is "applying" to the data[i].text and returning the text value, but it's not doing what I expected, which is create a new member of the collect object; it's just overwriting collect.i 20 times and leaving me with the last value.

Is there a different syntax I need to be using for assigning object members? I tried collect.i.text = and collect[i].text = and the error was that whatever I tried was undefined.

I'd love to know what's going on here, so the more in-depth an explanation the better.

Thanks!

+2  A: 

The reason you're seeing only one property in the object at the end is that you're not augmenting it in each loop iteration - you're overwriting it.

collect = { i : {text : data[i].text}};

This says: create an object with one property, i, whose value is another object with one property, text, and assign it to the variable collect. What you want to do instead is set a property of the existing collect object for each value of i, where i is the name of the property.

In order to create an object property where the name is set dynamically, you must use array-style syntax, like this: collect[i]. I don't think you can mix array syntax and object literal syntax like you've tried. Try this instead (disclaimer, not tested):

collect[i] = { text: data[i]["text"] };

Jimmy Cuadra
That worked. Any better way of explaining why though?
Alex Mcp
Edited to explain what's going on. :)
Jimmy Cuadra
A: 
 collect[i] = {text : data[i].text};

If you use collect[i].text, since collect[i] does not exist before the assignment, it will return undefined, which has no text property.

Also:

  1. collect.i means collect["i"]. This is totally different from collect[i].
  2. You can use an Array and append with .push.
KennyTM
A: 

As you already know, the problem is in this line:

 collect = { i : {text : data[i].text}};

Every iteration of the loop, you are erasing the collect object and assigning it a new object as value. That's why in the end it only shows the last iteration.

Try this:

 collect[i] = {text : data[i].text};
pixeline