[AngularJS] Best Practise - Resolve promises in router, defer controllers
See more: http://toddmotto.com/opinionated-angular-js-styleguide-for-teams/
/** * Created by Answer1215 on 1/13/2015. */ /** * Controller(s) * */ function AppController($rootScope, $location) { var appCtrl = this; $rootScope.$on('$routeChangeError', function(event, current, previous, rejection) { appCtrl.message = rejection.message; appCtrl.isError = true; }) appCtrl.goHome = function() { $location.path('/'); } } /** * Directive(s) * */ function ErrorDirective() { return { restrict: "EA", bindToController: true, controller: 'AppController', controllerAs: 'appCtrl', templateUrl: 'error.html' } } /** * Angular module * */ angular.module('app', [ 'ngRoute', 'app.home' ]) .constant('PEOPLE_URL', 'data.json') .controller('AppController', AppController) .directive('error', ErrorDirective) .config(function($routeProvider) { $routeProvider .when('/', { templateUrl: "home.html", controller: "HomeController", controllerAs: "homeCtrl", /* * resolve run first, prepare the data ready, * then controller & template show up * */ resolve: HomeController.resolve }); });
/** * Created by Answer1215 on 1/13/2015. */ function HomeController(loadPeople, getMessage) { var homeCtrl = this; homeCtrl.message = getMessage; homeCtrl.people = loadPeople; } HomeController.resolve = { loadPeople: function(SimpleDataService) { return SimpleDataService.getPeople(); }, getMessage : function(SimpleDataService) { return SimpleDataService.message; } } function SimpleDataService($http, $q, PEOPLE_URL) { var simpleData = {}; simpleData.people = []; simpleData.message = "Hello From Service"; simpleData.getPeople = function() { return fetchPeople().then(function(result) { return result.data; }); } function fetchPeople() { var defer = $q.defer(); $http.get(PEOPLE_URL) .success(function(data, status, headers, config) { simpleData.people = data; defer.resolve({data: data, message: "OK"}); }). error(function(data, status, headers, config) { if(status === 404){ data = data; defer.reject({data: data, message: "Cannot find " + config.url}); } }); return defer.promise; } return simpleData; } angular.module('app.home', []) .controller('HomeController', HomeController) .service('SimpleDataService', SimpleDataService);
While the routes are being resolved we want to show the user something to indicate progress. Angular will fire the $routeChangeStart
event as we navigate away from the page, which we can show some form of loading and ajax spinner, which can then be removed on the $routeChangeSuccess