0

I'm following the book "Pro AngularJS" by Adam Freeman. But I'm stuck at listing 15-10. The code he provided doesn't work at all.

The demo code is below. It's supposed to work in the following manner: when we click on the button to modify the prices, this list must update automatically. Would you please let me know how to fix his code? I've googled a lot but ....

<!doctype html>
<html ng-app="exampleApp">
<head>
    <script src="angular.js"></script>
    <link rel="stylesheet" href="bootstrap.css"/>
    <link rel="stylesheet" href="bootstrap-theme.css"/>
    <script>
        angular.module("exampleApp", [])
                .controller('defaultCtrl', function ($scope) {
                    $scope.products = [
                        {name: "Apples", category: "Fruit", price: 1.20, expiry: 10},
                        {name: "Bananas", category: "Fruit", price: 2.42, expiry: 7},
                        {name: "Pears", category: "Fruit", price: 2.02, expiry: 6}
                    ];
                    $scope.incrementPrices = function(){
                        for(var i=0; i< $scope.products.length; i++){
                            $scope.products[i].price += 1;
                        }
                    }
                })
                .directive("unorderedList", function () {
                    return function (scope, element, attrs) {
                        var data = scope[attrs["unorderedList"]];
                        var propertyExpression = attrs["listProperty"];

                        if (angular.isArray(data)) {
                            var listElem = angular.element("<ul>");
                            element.append(listElem);
                            for (var i = 0; i < data.length; i++) {
                                var itemElement = angular.element('<li>');
                                listElem.append(itemElement);
                                var watcherFn = function (watchScope) {
                                    return watchScope.$eval(propertyExpression, data[i]);
                                }
                                scope.$watch(watcherFn, function (newValue, oldValue) {
                                    itemElement.text(newValue);
                                });
                            }
                        }
                    }
                })

    </script>
</head>
<body ng-controller="defaultCtrl">
<div class="panel panel-default">
    <div class="panel-heading">
        <h3>Products</h3>
    </div>
    <div class="panel-body">
        <button class="btn btn-primary" ng-click="incrementPrices()">Change prices</button>
    </div>
    <div class="panel-body">
        <div unordered-list="products" list-property="price | currency"></div>
    </div>
</div>
</body>
</html>
2
  • Are there any errors appearing on console? Your watcherFN function seems to expect the scope as an input param, but in your $watch definition this is not provided to it - I'd expect an error along the lines of "cannot call $eval of undefined". Commented Dec 12, 2014 at 11:29
  • No there is no error, its a feature of the book, see my answer which comes from 15-11. Commented Dec 12, 2014 at 11:40

1 Answer 1

2

Just continue reading, in next capture 15-11 they will tell the previous code doesn't work.

If you load the directives.html file into the browser, the directive won’t keep the li elements up-to-date. If you look
at the HTML elements in the DOM, you will see that the li elements don’t contain any content. This is a problem that
is so common that I want to demonstrate how to fix it even though it results from a JavaScript, rather than AngularJS,
feature. 

Here code from 15-11 which adds function closure http://jsbin.com/ducihibahi/1/edit?html,output

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.