Search code examples
javascriptangularjsangularjs-directiveroute-provider

Trying to implement a directive with $rootScope and getting an TypeError: Cannot read property '$on' of undefined


I am trying add that is directive to my app which I got from this link: http://www.technofattie.com/2014/07/27/easy-loading-indicator-when-switching-views-in-angular.html

Here is the directive in my app:

var routeLoadingIndicator = angular.module('routeLoadingIndicator', [])
routeLoadingIndicator.directive('routeLoadingIndicator',    [function($rootScope){
  return {
  restrict:'E',
  template:"<h1 ng-if='isRouteLoading'>Loading...</h1>",
  link:function(scope, elem, attrs){
    scope.isRouteLoading = false;

  $rootScope.$on('$routeChangeStart', function(){
    scope.isRouteLoading = true;
  });

  $rootScope.$on('$routeChangeSuccess', function(){
    scope.isRouteLoading = false;
  });
}
};
}]);

Here is my app.js file:

var app = angular.module('app', ['addCarCtrl', 'galleryCtrl','detailCtrl', 'userCtrl', 'ngRoute', 'AuthService', 'ErrorService', 'CarService', 'angular-filepicker', 'ngPassword', 'ngMessages','ngAnimate', 'ngTouch', 'ngSanitize', 'ngMap', 'routeLoadingIndicator'])

  app.config(function($routeProvider){
      //The route provider handles the client request to switch route
      $routeProvider.when('/addCar', {
        templateUrl: 'partials/addCar.html',
        controller: 'addCarController'
      })
      .when('/addUser', {
        templateUrl: 'partials/addUser.html',
        controllerAs: 'userCtrl',
        controller: 'UserController'
      })
      .when('/gallery', {
        templateUrl: 'partials/gallery.html',
        controller: 'galleryController'
      })
      .when('/car/:id', {
        templateUrl: 'partials/car-view.html',
        controller: 'detailController'
      })
      .when('/detail/:id', {
        templateUrl: 'partials/detail.html',
        controller: 'addCarController'
      })
      .when('/login', {
        templateUrl: 'partials/login.html',
        controllerAs: 'userCtrl',
        controller: 'UserController'
      })
      .when('/home', {
        templateUrl: 'partials/home.html',
        controller: 'galleryController'
      })

  });

And this my the part of my html file with the directive:

  <div class="row">
    <route-loading-indicator></route-loading-indicator>
  </div>

  <div ng-if='!isRouteLoading' ng-view></div>

This is the error I am getting:

angular.js:13708 TypeError: Cannot read property '$on' of undefined
at Object.link 

I am not sure what I am missing or doing wrong any insights or suggestions would be awesome! Thanks!


Solution

  • There are few code errors as far as I know. I Have made few changes in order to make it functional. I guess it is working fine now. The errors are

    1. var routeLoadingIndicator = angular.module('routeLoadingIndicator', []) I don't think there is a module named routeLoadingIndicator in your project. It is a directive
    2. While you create a directive in that way you need to pass the first param as $rootScope and then the function

    var app = angular.module('app', ['ngRoute']);
    
    app.config(function($routeProvider) {
        //The route provider handles the client request to switch route
        $routeProvider.when('/addCar', {
            templateUrl: 'partials/addCar.html',
            controller: 'addCarController'
          })
          .when('/addUser', {
            templateUrl: 'partials/addUser.html',
            controllerAs: 'userCtrl',
            controller: 'UserController'
          })
          .when('/gallery', {
            templateUrl: 'partials/gallery.html',
            controller: 'galleryController'
          })
          .when('/car/:id', {
            templateUrl: 'partials/car-view.html',
            controller: 'detailController'
          })
          .when('/detail/:id', {
            templateUrl: 'partials/detail.html',
            controller: 'addCarController'
          })
          .when('/login', {
            templateUrl: 'partials/login.html',
            controllerAs: 'userCtrl',
            controller: 'UserController'
          })
          .when('/home', {
            templateUrl: 'partials/home.html',
            controller: 'galleryController'
          })
    
      })
      .directive('routeLoadingIndicator', ['$rootScope',
        function($rootScope) {
          return {
            restrict: 'E',
            template: "<h1 ng-if='isRouteLoading'>Loading...</h1>",
            link: function(scope, elem, attrs) {
              debugger;
              scope.isRouteLoading = false;
    
              $rootScope.$on('$routeChangeStart', function() {
                scope.isRouteLoading = true;
              });
    
              $rootScope.$on('$routeChangeSuccess', function() {
                scope.isRouteLoading = false;
              });
            }
          };
        }
      ]);
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular-route.min.js"></script>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular-loader.min.js"></script>
    
    <body ng-app="app">
      <div class="row">
        <route-loading-indicator></route-loading-indicator>
      </div>
    
      <div ng-if='!isRouteLoading' ng-view></div>
    </body>