Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS : directive function not called

The function that I'm providing to define my directive is never called. It used to work fine but suddenly stopped working and I have no idea why.

Here's my directive:

portalApp.directive('contactPanel', function () {
    console.log("NEVER SHOWN!");
    return {
        restrict: 'AE',
        replace: 'true',
        templateUrl: 'partials/account/contactPanel.html',
        scope: {
            contact: '=contact',
            primaryRoleName: '@',
            roleName: '@',
            primary: '=primary',
            locations: '=locations'
        },
        controller: function (userService, $rootScope, $scope) {
            ...snip...
        }
    };
});

and here an example of its use:

<contact-panel contact="user.account.contacts.billing" role-name="billing"
               locations="locations"></contact-panel>

Note that I'm using the correct casing, i.e. camel-case in JS and hyphenation in HTML.

The key clue is that the message that's logged in the second line (i.e. 'NEVER SHOWN!') never shows up in the console. If I log a message immediately before the directive declaration then that shows up, so this code is being executed by the interpreter, but the framework is just never using my declaration.

I'd love to have an answer obviously, but I'd also love to hear of some approaches to debug this kind of problem.

like image 830
HansA Avatar asked Jan 07 '23 13:01

HansA


2 Answers

I can see only 2 possibilities that would exhibit the behavior you described. Either the HTML with the directive was not compiled or the directive is not registered.

The "not compiled" case could be because the directive is used outside of the Angular app, for example:

<div ng-app="portalApp">
 ...
</div>
...
<contact-panel></contact-panel>

Or, if you added the HTML dynamically, but did not $compile and link it.

The "not registered" case could be due to re-registration of the app's module. In other words, you might have the following case:

var portalApp = angular.module("portalApp", []);
portalApp.directive("contactPanel", function(){...});

// then elsewhere you use a setter:

angular.module("portalApp", []).controller("FooCtrl", function(){});    
// instead of the getter:
// var app = angular.module("portalApp");

The second call to angular.module("portalApp", []) removes the previous registration of .directive("contactPanel", ....

like image 149
New Dev Avatar answered Jan 21 '23 21:01

New Dev


I figured out the cause of this problem. At some point I must've accidentally moved the directive into a configuration block like this:

portalApp.config(function ($stateProvider, $urlRouterProvider) {
    portalApp.directive('contactPanel', function () {
        console.log("NEVER SHOWN!");
        return {
            ...snip...
        };
    });
});

Once I moved it back out of the configuration block and into the global scope the directive immediately rendered as it should.

The reason why this doesn't work is that angular runs the configuration code after it's run the directives, like this:

runInvokeQueue(moduleFn._invokeQueue);    // runs directives
runInvokeQueue(moduleFn._configBlocks);   // runs config blocks

So things added to the _invokeQueue (which the directive() function does) from within a config block will never be executed.

Thank you to all those who tried to help.

like image 35
HansA Avatar answered Jan 21 '23 21:01

HansA