0

I have managed to create an object connecting to an API. So I have a function loadColors()

loadColors = function() {

            var Colors = [];
            for (var i =0; i < array.length; i++) {

                Card.get({cardName: array[i].object_name}, function(data) {

                    Colors.push(data.data[0].color);

                });

            }
            return {Colors};
        };
        var Colors = loadColor();

and inside there I was able to see the result with console.log(Colors) which is:

    Object {Colors: Array[0]}
    Colors: Array[4]
    0: "green"
    1: "red"
    2: "yellow"
    3: "blue"
    length: 4
    __proto__: Array[0]
    __proto__: Object

When I try to access a value like console.log[Colors[0]]; I get undefined. What am I doing wring?

  • 2
    *"When I try to access a value I fail"* Well, what do those attempts look like? Please take the [tour], have a look around, and read through the [help], in particular [*How do I ask a good question?*](/help/how-to-ask) – T.J. Crowder Dec 15 '15 at 19:45
  • Is the typo only in your example? Your function is called 'loadColors()' and you call Colors=loadColor (without s) – Rik Dec 15 '15 at 20:38
  • yes in the code it's loadColors() – Dimitrios Vythoulkas Dec 15 '15 at 21:17

2 Answers2

3

Why are you wrapping Colors in {} in your return statements?

Just do return Colors; and you would be able to access the indexed array items directly from the return result.

Since you're currently returning an object containing the array, you would have to access it by Colors.Colors[0].


Update

I realize that besides wrapping your result in an object before returning it, you are also returning an array that is not populated with items at the return point, due to the asynchronous nature of Card.get.

This problem is actually rather well suited for a concept called Promises, but rather than introducing another new concept at this point, I will illustrate how you can solve this manually. (IE doensn't have native Promise support, there are frameworks that will solve this but you may not want an entire new framework just for this. jQuery has something called Deferreds, but they're subtly different from the Promise specs).

Instead of returning a result from the function, the callback from Card.get should call the function that moves your code forward. It should only do this once the array is filled, however, and not once for every callback.

Card.get({ your options }, function(data) {
    Colors.push(data.data[0].color);
    if(Colors.length == array.length) {
        allColorsLoaded(Colors);
    }
});

So if your logic is currently:

var Colors = loadColors();
alert(Colors.length);

It would need to be updated so that everything that relies on Colors to be populated is initiated by the callback:

var allColorsLoaded = function(Colors) {
   alert(Colors.length);
};
loadColors();
David Hedlund
  • 128,221
  • 31
  • 203
  • 222
  • what happens when he does that? What is actually being returned? I mean, what is the key for the Colors object within the returned object? Sorry, my mind just wandered when I saw the syntax... – pQuestions123 Dec 15 '15 at 20:39
  • With a named variable, the returned result will be an object with a property of that name. `var test = [1,2,3]; var Colors = {test};` will be equal to `var Colors = { test: [1,2,3] }` in this case, which is indeed what you're seeing in the `console.log` output pasted. – David Hedlund Dec 15 '15 at 20:43
  • See the section [New notations in ECMAScript 2015](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer) – David Hedlund Dec 15 '15 at 20:47
  • I did that and I get an empty array. In the next line after the push command, the log is 4 iterations when I see the Colors Array being populated. When it steps out still inside the for I get 4 times an empty array if I log it. it seems like the values change. Why? – Dimitrios Vythoulkas Dec 15 '15 at 21:58
  • @mosmic: Sorry, I got distracted by the `{Colors}` thing and didn't spot `Card.get`. That's a different issue entirely. `Colors` is being populated in a callback function, I assume asynchronously. In this scenario you can't use a return value at all, since the array won't be filled until after the function completes. You will need to rely on callbacks instead. – David Hedlund Dec 15 '15 at 22:45
  • [See this question, among many others, for more info on asynchronous](http://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron) – David Hedlund Dec 15 '15 at 22:47
  • @DavidHedlund It seems that this is the issue. But since I'm new to this would you suggest a solution or point me how to use callbacks? Thanks – Dimitrios Vythoulkas Dec 15 '15 at 22:50
  • @DavidHedlund Thank you very much for all the help. I'm heading that way with callbacks. Still can't figure out how I'm able to console log the object from outside the function when I use curly braces and not being able to access it's elements with the way you mentioned.(Colors.Colors[0]) – Dimitrios Vythoulkas Dec 15 '15 at 23:38
  • @mosmic: Those are different issues. I think you're being confused by the fact that both the variable in the function, and the variable that is the function result are called `Colors`. Let's assume instead that you were calling it `var foo = loadColors()`. The fact that you're returning `{Colors}` rather than `Colors` means that the value of `foo` will be `{ Colors: [] }` rather than just `[]`. You will be able to access `foo.Colors`, which will be your empty array, but not `foo.Colors[0]` because there is nothing at that index. That is due to your primary issue, `Card.get` being async. – David Hedlund Dec 16 '15 at 06:51
2

It is isn't so clear from the question what is going on but from what I understood, when you try

console.log(Colors[0])

outside the function it returns undefined while inside the function it returns 'green'?

If so you should probably just change:

return {Colors};

to be:

return Colors;
pQuestions123
  • 4,471
  • 6
  • 28
  • 59
  • I made the changed you suggested and my result is an empty array. I tried to find where the problem is. In the next line after the push the log is 4 iterations when I see the Colors Array being populated. When it steps out still inside the for I get 4 times an empty array if I log it. it seems like the values change. Why? – Dimitrios Vythoulkas Dec 15 '15 at 21:55