1

I am a newbie in JavaScript and AngularJS. I was trying out looping a object, get its key-value pair and then use it to build an array of new objects.

var actorMovie = { "Leonardo DiCaprio" : "The Revenant", "Christian Bale" : "The Dark Knight Rises", "Sylvester Stallone" : "Rocky" }; if(actorMovie){ var actorMovieArray = []; angular.forEach(actorMovie, function(value, key) { actorMovieArray.push ({key: { "Movies": { "Best Movie": value } }}); }); } console.log(actorMovieArray); 

This console log prints out the right values, but the key remains as 'key' and never updated to the actor's name as expected. What am I doing wrong here? I tried searching for an answer but did not find any solution. Am I missing something?

0

    3 Answers 3

    1

    I would do something like

    angular.forEach(actorMovie, function(value, key) { actorMovieArray[key]= { "Movies": { "Best Movie": value } }; }); 

    In your code, javascript does not know that you want to evaluate the key variable to assign the property, and considers the key to be the key string.

    3
    • Worked like a charm. Thank you.
      – Sunil
      CommentedMar 6, 2016 at 10:40
    • However, I would like to know in my code, how JS evaluates value but not key?
      – Sunil
      CommentedMar 6, 2016 at 10:43
    • When you create an object, and assign properties, the value on the left of the : is considered as a string and not a variable. However, the value on the right is a variable, and therefore gets evaluated.CommentedMar 6, 2016 at 10:46
    0

    As @Hugues pointed out, there is no way for JavaScript to know if you mean the key as literal or as variable, so the literal value is used.

    Please be aware that the answer does not behave the same way as you wanted to in your question. Using the key as an array identifier has two drawbacks:

    • the order of the items when iterating over the keys cannot be retained
    • if there are two items having the same key (here the actor name), you will only get one in the result as you are overwriting some previously added value. (this is not really the case as your input already is an object literal so that duplicate keys are no concern, but could be a problem when switching to some other input, e.g. an array of items)

    This could be okay for you as long as order doesn't matter and you know your keys are unique. If you want the structure as defined in your question, please consider the following snippet:

    function buildItem(value, key) { var res = {}; res[key] = { "Movies": { "Best Movie": value } }; return res; } if(actorMovie){ var actorMovieArray = []; angular.forEach(actorMovie, function(value, key) { actorMovieArray.push(buildItem(value, key)); }); } 

    Try out this jsbin: http://jsbin.com/luborejini/edit?js,console

      0

      I would use Object.keys and Array.forEach on the resulting array. And I would also embrace Javascript's functional nature. That way you could easily pull out the creator function into factory mapping libraries for your api json data.

      if(actorMovie){ var actorMovieArray = []; Object.keys(actorMovie).forEach(function(actor){ actorMovieArray[actor] = function(){ return { Movies: { BestMovie: actorMovie[actor] } }; }(); }); 

      }

      I would also recommend not using the actor name as the key in the array. I would rather map it to a model structure, it will make your views / controllers cleaner and easier to understand:

      if(actorMovie){ var actorMovieArray = []; Object.keys(actorMovie).forEach(function(actor) { actorMovieArray.push(function(){ return { Actor: actor, Movies: { BestMovie: actorMovie[actor] } }; }()); }); 

      }

      This will drive you into more concise view models, and set you up for easy refactoring once your structure is in place. It will also make testing easier, at least in my opinion.

        Start asking to get answers

        Find the answer to your question by asking.

        Ask question

        Explore related questions

        See similar questions with these tags.