0

Trying to wrap my head around why this is not working. When I have my $http.get in my controller, I can convert the number stored in the JSON file to a array element like so:

$http.get('weapon.json').success(function(data) {
    $scope.weapons = data;

    for(i=0, len=$scope.weapons.length; i < len; i++){
        $scope.weapons[i].ele = $scope.elementType[$scope.weapons[i].ele];
    }
});

But when I try and move my $http.get into a factory, $scope.weapons[i].ele equal null instead of the array element.

.factory('WeaponData', function($http){
    return $http.get('weapon.json');
})

.controller('BL2Ctrl', function($scope,WeaponData) {
    WeaponData.success(function(data) {
        $scope.weapons = data;

        for(i=0, len=$scope.weapons.length; i < len; i++){
            $scope.weapons[i].ele = $scope.elementType[$scope.weapons[i].ele];
        }
    });
})

here is a Plunker where it doesn't work

1 Answer 1

1

The problem is that your controller is being instantiated 3 times. Therefore, its constructor is being run 3 times and the data returned from your $http.get is being updated 3 times (since you set up the success handler 3 times). After the first time, it has the values you are wanting; the 2, 3, and 3 are replaced with the respective objects from your elementType list. The problem is that the second and third times the success handler is called, the list is updated again, but ele attribute has already been overwritten. Therefore, it gets updated to undefined because there is no property of the elementType object which matches the key [object Object] (or whatever the string value ends up being). There are a few ways to solve this:

  1. Create a larger factory and push the update to weapon[i].ele into the factory. http://plnkr.co/edit/CSv3ZRSL9K3bOcc9fcMJ
  2. Use elementType[weaponStats.ele] in the view, rather than updating the model. http://plnkr.co/edit/UqVz88hVvNATO42A2Aew
  3. Update a different attribute (e.g. eleType) instead of overwriting ele. This will prevent you from losing the value loaded from the JSON. (You'll still be updating the objects 3 times.) http://plnkr.co/edit/EqbXUT6gCthtGbC7VQHO

On a separate note, I noticed that you are binding the controller to one of the <div>s around the ng-repeat, but you also declare that the controller for the weaponblock directive is the same controller. This means you're redoing all of that work for each directive even though you don't need to. Here is a partial rewrite which splits up the single controller you had into 1 controller to set up the data and a separate controller to set up the functions for the directive: http://plnkr.co/edit/6NpcuZLJutdC9rtwhJXd

4
  • 1. Not sure how I would use weaponStats.ele in the factory. SOrry for the miss communication. The way I had it working before was with no factory service at all. Like this Plunker Commented Feb 14, 2014 at 3:49
  • 1. Not sure how I would use weaponStats.ele in the factory. SOrry for the miss communication. The way I had it working before was with no factory service at all. Like this Plunker 2. I tried this way before, but it breaks the select dropdown. 3. This works, but is it the most effective way? I was passing the whole elementType attribute that I wanted in the JSON, but I went with the number trying to fix another problem I had with the select for weaponStats.ele defaulting to blank in the view. Commented Feb 14, 2014 at 3:57
  • Yeah, I noticed the same problem with 3. That was actually caused by the problem I note at the bottom of my updated answer. Basically you were creating a new set of elementType objects that only one of your weaponblock directives could see. I added working examples for each of the options I discussed. I think that the first option is probably the best one; that's why I used it as the basis for my final update suggestion. Commented Feb 14, 2014 at 5:52
  • Thank you so much for such a thorough answer and multiple solutions! Commented Feb 14, 2014 at 16:23

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.