2

I have a page that will show a list of items. The list of items can be be constantly changing, so whenever the use goes to this page or refreshes the page, he would see the new list of items.

I am currently use Parse to store my items and I will use a promise to interact with the Parse API and get my items. A very simplified example is below.

The basic flow is that when index.html is shown, HomeCtrl.js will load and call ItemService.getItems() to get the items, attach them to $scope.items and then display any changes to the view. ItemService.getItems() is a promise provided from the Parse API.

app.js

var myApp = angular.module('myApp',[]);
// Parse API keys
Parse.initialize('MCNXFhdenmpSRN1DU8EJrG3YROXaX4bg0Q5IYwKp', 'XZfWd7J9xGSZQOizu0BoAtIUYtECdci4o6yR76YN');

index.html

<html ng-app = 'myApp'>
<script src="//www.parsecdn.com/js/parse-1.6.2.min.js"></script>

<head>
    <title> My Simple Example that doesn't work! </title>
</head>

<body layout="row">

    <div ng-controller = "HomeCtrl as ctrl">
        <div ng-repeat="item in ctrl.items">
            {{item.id}}
        </div>
    </div>  

    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.6/angular.min.js"></script>
    <script src = "app.js"> </script>
    <script src = "HomeCtrl.js"> </script>
    <script src = "ItemService.js"> </script>

</body>
</html>

ItemService.js

var myApp = angular.module('myApp');
myApp.service('ItemService', function(){

// gets all Items
this.getItems = function() {
    var Item = Parse.Object.extend("Item");
    var query = new Parse.Query(Item);

    return query.find().then(function(items){
      return items;
    });
    return this;
  }

});

HomeCtrl.js

var myApp = angular.module('myApp');
myApp.controller('HomeCtrl',[ 'ItemService', '$scope',function(ItemService, $scope){

    $scope.items = [];

    ItemService.getItems()
        .then(function(results){
            $scope.$apply(function() {
                $scope.items = results;
                console.log($scope.items);
            });
        });

    console.log($scope.items);
}]);

$scope.items does change in the $scope.$apply function (I print it out and can see some items) , however it is not changed for the view. When I print $scope.items after ItemService.getItems(), I print out an empty array.

Am I incorrectly updating $scope.items after calling the promise or is there some concept that I am not understanding?

Any help is appreciated.


EDIT

from 456's answer, I see that I made a mistake in my ng-repeat and his answer works. However I would like to keep using controllerAs syntax. I have tried to update this.items in a $scope.$apply function but it does not work - this.items is modified, but the change is not represented in the view. My modifications are below

index.html

<div ng-controller = "HomeCtrl as ctrl">
    <div ng-repeat="item in ctrl.items">
        {{item.id}}
    </div>
</div>  

HomeCtrl.js

var myApp = angular.module('myApp');
myApp.controller('HomeCtrl',[ 'ItemService', '$scope',function(ItemService, $scope){

    this.items = [];

    ItemService.getItems()
        .then(function(results){
            $scope.$apply(function() {
                this.items = results;
                console.log(this.items);
            });
        });
}]);
Rohan
  • 1,312
  • 3
  • 17
  • 43
  • If you are using controllerAs syntax in you HTML,you don't need to use $scope in your controller.You can add those elements on this variable on this property in the controller. – Mahendra Singh Nov 20 '15 at 06:14
  • @MahendraSingh I have to use $scope in controller to use $apply to update the view. Is there a way I can continue to use 'this' and get the same affect of $apply? – Rohan Nov 20 '15 at 06:21
  • Sure you can use $scope.apply, but your items list need not to be on scope. – Mahendra Singh Nov 20 '15 at 06:23
  • @MahendraSingh please check my edit. I use $scope.$apply with this.items and the view is not being updated. Did I do something wrong? – Rohan Nov 20 '15 at 19:03

2 Answers2

2

The error you are getting is due to the fact that 'this' will point to the window object when the control comes to your then function.

ItemService.getItems()
    .then(function(results){
        //Here 'this' will point to window 
       //window.items is undefined
    });

Hence the error.

You can solve this in many ways,one of which is using another object to point to this.

var myApp = angular.module('myApp');

myApp.controller('HomeCtrl',[ 'ItemService', '$scope',function(ItemService, $scope){

var that = this;
that.items = [];

ItemService.getItems()
    .then(function(results){
            that.items = results;
    });
}]);

Try this if it works for you.

Mahendra Singh
  • 298
  • 2
  • 9
1

U should call it in html like this-

 <div ng-repeat="item in items">
Disha
  • 822
  • 1
  • 10
  • 39
  • This does work, but is there a way I can maintain the controller-as syntax? – Rohan Nov 20 '15 at 06:20
  • you can declare items object in controller as this.items = []; , instead of $scope.items = []; – Disha Nov 20 '15 at 06:24
  • Please check my edit. I declare the items as this.items and modify it in $scope.$apply, but the view is not changed. Did I do something wrong? – Rohan Nov 20 '15 at 19:04