Arturo Rojas Arturo Rojas - 3 months ago 37
AngularJS Question

ion-list does not refresh after $state.go is called

I am learning AngularJS and ionic framework using this tutorial:

http://www.htmlxprs.com/post/12/tutorial-on-using-parse-rest-api-and-ionic-framework-together

Everything works well up until the point when I create a new item in the createTodo state and then call $state.go('todos') to go back to my items list, here is the code for the create Todo Controller:

.controller('TodoCreateController', ['$scope', 'Todo', '$state', function($scope, Todo, $state) {
$scope.todo = {};

$scope.create = function() {
Todo.create({content: $scope.todo.content}).success(function(data) {
$state.go('todos', {}, {reload: true});
});
}
}])


Here is the code for the item list controller:

.controller('TodoListController', ['$scope', 'Todo', '$state', function($scope, Todo) {
Todo.getAll().success(function(data) {
$scope.items = data.results;
});

$scope.deleteItem = function(item) {
Todo.delete(item.objectId);
$scope.items.splice($scope.items.indexOf(item), 1);
};
}])


Here are the states configured

.config(function($stateProvider) {
$stateProvider.state('todos', {
url: '/todos',
controller: 'TodoListController',
templateUrl: 'views/todos.html'
}).state('createTodo', {
url: '/todo/new',
controller: 'TodoCreateController',
templateUrl: 'views/create-todo.html'
});
})


When the application starts, the method of the TodoListController is invoked thanks to the last line added and the end of the .run method in the main app.js (or at least thats my understanding):

.run(function($ionicPlatform, $state) {
$ionicPlatform.ready(function() {

if(window.cordova && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
}
if(window.StatusBar) {
StatusBar.styleDefault();
}
});

$state.go('todos');
})


My problem is that, as soon as the new item is created and I invoke $state.go('todos') from the TodoCreateController, it takes me back to the item list but the new item is not there and the method of the TodoListController is never invoked, therefore leaving the list outdated.

How can I refresh the list in the 'todos' state after a new item has been created?

Answer

I found a rather elegant solution:

Inside my TodoListController I define an event listener like this:

$rootScope.$on('todo:listChanged', function() {
    $scope.updateList();
});

then comes the updateList() method

$scope.updateList = function() {
    Todo.getAll().success(function(data) {
        $scope.items = data.results;
    });
};

And finally in the TodoCreateController I $emit the event upwards as soon as the item is created and right before changing state

$scope.create = function() {
    Todo.create({content: $scope.todo.content}).success(function(data) {
        $scope.$emit('todo:listChanged');
        $state.go('todos');
    });
};

And voila! The list updates accordingly and I can now use the same event if I delete or update a list item