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.

Sign up to request clarification or add additional context in comments.

3 Comments

Worked like a charm. Thank you.
However, I would like to know in my code, how JS evaluates value but not key?
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.
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

Comments

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.