1

I'm building a simple Angular test app and have run into a problem. I have a list of items and an "add item" link at the bottom of the list (the list is stored on a simple NodeJS server). This "add item" link loads a child view that lets the user set the name of the new item. When the user clicks done the item is added to the list on the server, then tells the parent list to update. In the console I can see that the data is being passed back to the parent but the view isn't reflecting the new list of items. I've looked into $scope.$apply but as I am never using a third party library I have no reason to use it (I have tried it and it always gives the error "$digest is already running" which seems expected after looking at the docs). Here's the code in question:

HTML Parent List

<ul data-ng-controller="listCntrl">
    <li data-ng-repeat="item in items">
        <a href="#/item/{{item.name}}">{{item.name}}</a>
    </li>
    <li><a href="#/new">Add Item</a></li>
</ul>
<div data-ui-view></div> <!--Child view loaded here-->

HTML Child View

<div data-ng-controller="newItemCntrl">
    <input type="text" data-ng-model="name"></input>
    <a data-ng-click="addItem()">Done</a>
</div>

Controllers

app.controller('listCntrl',function($scope, ListFactory){
    ListFactory.getItems().success(function(data){
        $scope.items = data;
    });

    $scope.update = function(){
        ListFactory.getItems().success(function(data){
            console.log(data); //The correct list is in data
            $scope.items = data; //This doesn't cause the view to update!
        });
    }
});

app.controller('newItemCntrl',function($scope){
    $scope.addItem = function(){
        $http({
            method: 'POST',
            url: '/addItem',
            data: JSON.stringify( {name: $scope.name} ),
            headers: {'Content-Type': 'application/json'},
        })
        .success(function(){
            $scope.$parent.update();
        });
    }
});

Factory

app.factory('ListFactory', function($http){ 
    return {
        getItems: function(){
            return $http({
                method: 'POST',
                url: '/getItems',
                headers: {'Content-Type': 'application/json'}
            });
        }
    }               
});

Everything works on the server side and in the update() function it prints out the updated list, but somehow the $scope.items assignment isn't causing the list view to update. If I refresh the page then the list appears correctly. What am I doing wrong here? I'm guessing it's a problem with my understanding of the $scope.$parent but I can't seem to figure it out. Thanks for you help!

1 Answer 1

3

The 'listCntrl' controller is on the element, while the 'newItemCtrl' is bound to a child view of data-ui-view, which is a sibling of the element, not a child.

Thus, the scope created in newItemCtrl does not have the scope created by listCntrl in its parent chain.

Try something like this:

<div data-ng-controller="listCntrl">
    <ul>
        <li data-ng-repeat="item in items">
            <a href="#/item/{{item.name}}">{{item.name}}</a>
        </li>
        <li><a href="#/new">Add Item</a></li>
    </ul>
    <div data-ui-view></div> <!--Child view loaded here-->
</div>

BTW, you don't actually need to use $scope.$parent in this case. All child scopes (but not isolated scopes) have prototypical inheritance from their parents, i.e. scope.__proto__ === scope.$parent. Just using $scope.update() should suffice, as long as no directive between this scope and the parent scope that defined the update function made an isolated scope.

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

2 Comments

That's a good catch. I don't understand how the "update" function was getting called at all though...
I think he ran the update method via other means, and not through the addItem method.

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.