Search code examples
javascriptangularjsangular-controllerangularjs-events

Stop event listeners on '$destroy'. TypeError: $on is not a function;


I'm trying to stop all event listeners while scope is destroyed.

I get this error:

TypeError: vm.$on is not a function; 

Neither vm.on(..) works

    angular.module('app.layout')
      .controller('DashboardController', DashboardController);

      DashboardController.$inject = ['$interval','dataservice'];


      function DashboardController($interval, dataservice) {
        var vm = this;
        vm.name = "DashboardController";


        console.log('Init Dashboard Controller');
        initEvents();
/*
 ...
*/

    /////////////////////////////

    function initEvents() {
          vm.$on('$destroy', function() {
            vm.stop();
            console.log('DashboardController scope destroyed.');
          })
        }

Solution

  • The problem is that vm doesn't have the $on(... declared, you must use $scope instead. Inject it on your controller and declare like $scope.$on.

    When using controllerAs syntax, this very often missunderstood that you shouldn't use $scope at all. However, the recomendation is to avoid using $scope for certain activities not abolish it from your controller. Scope always will exists, it's an internal of your controller, just don't use it like a view model, but you can use it anyways for such tasks like, listen to events, broadcast, emmit, etc.

    Try something like (after you've injected $scope on your dependencies):

    $scope.$on('$destroy', function() {
        vm.stop();
        console.log('DashboardController scope destroyed.');
    })