Here's my setup, I have a backend API running on Tomcat and built in Spring and the frontend in Angular JS, data is passed back and forth via JSON. All operations on the backend API were tested with the REST console and the Angular app as well. The app is a CRUD for Teams which are described by an id, a name and a team rating , for example :
[{"id":69,"name":"test","rating":5},{"id":70,"name":"test 2","rating":6}]
I noticed that my views aren't updated after I add a new team or delete a new team even though the POST or DELETE requests executed successfully and the changes are reflected in the database (MySQL).
I'm not sure if I need to manually invoke $scope.$apply or if I need to implement promises to make the app work.
app.js
var teamApp = angular.module('teamApp',[
'ngRoute',
'teamControllers',
'teamServices'
]);
teamApp.config(['$httpProvider', function($httpProvider) {
delete $httpProvider.defaults.headers.common["X-Requested-With"];
}]);
teamApp.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/teams', {
templateUrl: 'views/team-list.html',
controller: 'teamController'
}).
when('/team/:teamId', {
templateUrl: 'views/team-detail.html',
controller: 'teamDetailController'
}).
when('/teams/create', {
templateUrl: 'views/team-create.html',
controller: 'teamCreateController'
}).
otherwise({
redirectTo: '/teams'
});
}]);
controllers.js
var teamControllers = angular.module('teamControllers', []);
teamControllers.controller('teamController',
['$scope', 'Teams', 'Teams', '$location',
function($scope, Teams, Team, $location) {
$scope.viewTeam = function(teamId) {
$location.path('/team/'+teamId);
};
$scope.createTeam = function () {
$location.path('/teams/create');
};
$scope.teams = Teams.query();
$scope.teams.$promise.then(function(result){
console.log('Success ' + result);
$scope.teams = result;
});
}]);
teamControllers.controller('teamDetailController',
['$scope', '$routeParams', 'Team', '$location',
function($scope, $routeParams, Team, $location){
$scope.cancel = function() {
$location.path('/teams');
};
$scope.deleteTeam = function(teamId) {
Team.delete({teamId: teamId});
$location.path('/teams');
};
$scope.team = Team.show({teamId: $routeParams.teamId});
}]);
teamControllers.controller('teamCreateController',
['$scope', 'Teams', '$location',
function($scope, Teams, $location){
$scope.createTeam = function() {
Teams.create($scope.team);
$location.path('/teams');
}
$scope.cancel = function() {
$location.path('/teams');
};
}]);
services.js
var teamServices = angular.module('teamServices', ['ngResource']);
teamServices.factory('Teams', ['$resource',
function($resource){
return $resource('http://localhost:8080/api/teams', {}, {
query: {method:'GET', isArray:true},
create: {method:'POST'}
});
}]);
teamServices.factory('Team', ['$resource',
function($resource){
return $resource('http://localhost:8080/api/team/:teamId', {}, {
show : {
method:'GET'
},
delete : {
method:'DELETE'
}
});
}]);
index.html
<html lang="en" ng-app="teamApp">
<head>
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/themes/smoothness/jquery-ui.css" />
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap-theme.min.css">
<style>
body {
padding-top: 60px;
}
@media (max-width: 980px) {
body {
padding-top: 0;
}
}
</style>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular-route.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular-resource.min.js"></script>
<script src="js/app.js"></script>
<script src="js/controllers.js"></script>
<script src="js/services.js"></script>
</head>
<body>
<div ng-view></div>
</body>
</html>
Solution
In the controllers.js I've changed the createTeam and deleteTeam calls and used promises, for example:
Before:
$scope.createTeam = function() {
Teams.create($scope.team);
$location.path('/teams');
}
After:
$scope.createTeam = function() {
Teams.create($scope.team).$promise.then(
function(result){
console.log('Success' + result);
$location.path('/teams');
},
function(error){
alert(error);
console.log(error);
}
);
}