Search code examples
javascriptangularjsangularjs-directiveeventemitterangularjs-rootscope

AngularJS rootScope.$emit from within Directive


I have a directive for users to like (or "fave") posts in my application. Throughout my controllers I use $rootScope.$emit('name-of-function', some-id) to update user data when they like a new post, as this is reflected throughout my application. But I can't seem to use $rootScope.$emit in the directive. I receive an error

$rootScope.$emit is not a function

Presumably the $rootScope.$on event which corresponds with this command has not been called yet, so this function does not yet exist? What can be done about this? Is there a better way to arrange this?

var module = angular.module('directives.module');

module.directive('postFave', function (contentService, $rootScope) {
return {
    restrict: 'E',
    templateUrl: 'directives/post-fave.html',
    scope: {
        contentId: '@',
        slug: '@'
    },
    link: function ($scope, $rootScope, element) {

        $scope.contentFavToggle = function (ev) {
            contentId = $scope.contentId;
            contentService.contentFavToggle(contentId, ev).then(function (response) {
                $rootScope.$emit('dataUpdated', $scope.slug);
                if (response) {
                    $scope.favourite[contentId] = response;
                } else {
                    $scope.favourite[contentId] = null;
                }
            });
        };

        console.log("track fave directive called");
    }
};
});

from controller:

var dataUpdatedListener = $rootScope.$on('dataUpdated', function (event, slug) {
    dataService.clearData(slug);
    dataControllerInit();
});

How can I access this rootscope function from within the directive? Thanks.

FYI - "link" has been used in the directive because this is related to an instance of an HTML element which will be used a number of times on the page


Solution

  • link has the following signature, there is no need to add $rootScope injection into link function:

    function link(scope, element, attrs, controller, transcludeFn) { ... }
    

    Remove it from link and it will work.