AngularJS : basic routing with $routeProvider and route resolvements

AngularJS : ngRoute state resolvement example. Data service loading initial state data and visualizing through a custom directive with ControllerAs, bindToController and isolated scope syntax.

by Daan De Smedt

HTML

<script src="https://code.angularjs.org/1.4.8/angular-route.js"></script>
<!--
  AngularJS
  ----------
  basic routing with $routeProvider and route resolvement. 
  View templates are binded using the text/ng-template tag. Inject 'ngRoute' as dependency. 
-->

<div ng-app="app">

  <!-- page view template file -->
  <script type="text/ng-template" id="views/home.html">
    <b>GITHUB PUBLIC USERS</b>
    <br/>
    <br/>
    <git-hub-user-info user="user" ng-repeat="user in vm.users track by $index"></git-hub-user-info>
    <br/>
    <br/>
    <button ng-click="vm.reloadUsers()">Reload data</button>
    <button ng-click="vm.removeUsers()">Remove data</button>
  </script>
  
  <script type="text/ng-template" id="views/about.html">
    <b>ABOUT PAGE</b>
    <p>Basic routing with $routeProvider and route resolvement example.<br/>
    View templates are binded using the text/ng-template tag. Inject 'ngRoute' as dependency. </p>
  </script>

  <!-- directive view template -->
  <script type="text/ng-template" id="views/user/github/info.html">
    <div>
      <img width="40px" height="40px" ng-src="{{::vm.user.avatar_url}}" />
      <span style="float:right;">
          {{::vm.user.login}} 
          <span style="font-weight:bold;text-transform:uppercase;font-size:11px;color:gray;">
            | {{::vm.user.type}}
          </span>
      <button ng-click="vm.alertURL()">Get GitHub URL</button>
      </span>
    </div>
  </script>

  <!-- navigation -->
  <div>
    <a href="#/home">Home (public users)</a>
    <a style="margin-left: 15px;" href="#/about">About</a>
  </div>
  
  <br/><br/>
  
  <!-- ng-view container -->
  <div ng-view></div>

</div>

JavaScript

angular
  .module('app', ['ngRoute'])
  .controller('BasicController', BasicController)
  .factory('githubDataService', githubDataService)
  .directive('gitHubUserInfo', gitHubUserInfo)
  .config(RouteConfig)

/* define routes with controller & controllerAs syntax */
function RouteConfig($routeProvider) {
  $routeProvider
    .when('/home', {
      templateUrl: 'views/home.html',
      controller: 'BasicController',
      controllerAs: 'vm',
      resolve: {
        loadUsers: function loadUsers(githubDataService) {
          return githubDataService.loadUsers();
        }
      }
    })
    .when('/about', {
      templateUrl: 'views/about.html'      
    })
    .otherwise('/home');
}

function loadUsers(githubDataService) {
  return githubDataService.loadUsers();
}


/* directive */
function gitHubUserInfo() {
  var directive = {
    scope: {
      user: "="
    },
    link: link,
    templateUrl: 'views/user/github/info.html',
    controller: GitHubDirectiveController,
    controllerAs: 'vm',
    bindToController: true,
    restrict: 'EA'
  };
  return directive;

  function link(scope, element, attrs) {
    /* add clean-up listeren */
    element.on('$destroy', function() {
      console.log('directive $destroy event listeren');
      scope.$destroy();
    });
  }

  function GitHubDirectiveController($scope) {
    var vm = this;
    vm.alertURL = alertURL;

    function alertURL() {
      alert($scope.vm.user.url);
    }
  }

}

/* controller */
function BasicController(githubDataService) {
  var vm = this;
  vm.users = githubDataService.getUsers();
  vm.reloadUsers = reloadUsers;
  vm.removeUsers = removeUsers;

  function reloadUsers() {
    removeUsers();
    githubDataService.loadUsers()
      .then(function(data) {
        vm.users = data;
      });
  }

  function removeUsers() {
    vm.users = [];
  }

}

/* service */
function githubDataService($http, $q) {
  var users;

  return {
    loadUsers: loadUsers,
    getUsers: getUsers
  };

  function...