0

In my JSFiddle I have this directive.

(function() {

    angular.module('myApp', [])
        .directive('appFoo', appFoo);

    function appFoo() {

        console.log('Directive Factory runs');

        return {
            controller: AppFooController,
            link: link,
            replace: true,
            restrict: 'E',
            scope: {
                parentProp: '='
            }
        };

        function AppFooController($scope) {

            console.log('Controller runs');

            $scope.render({
                some: 'data'
            });

        }

        function link($scope, $element) {

            console.log('Link function runs');

            $scope.render = function(data) {
                console.log(shared.$scope.parentProp, $element[0], data);
            };

        }

    }

}());

And this Jasmine Spec;

describe('myApp::appFoo', function() {

    var shared;

    beforeEach(function() {

        shared = {};
        shared.markup = '<app-foo parent-prop="someProp"></app-foo>';

        inject(function($compile, $rootScope) {
            shared.$compile = $compile;
            shared.$parentScope = $rootScope.$new(true);
            shared.$rootScope = $rootScope;
        });

        shared.createDirective = function() {
            shared.$element = angular.element(shared.markup);
            shared.$compile(shared.$element)(shared.$parentScope);
            shared.$parentScope.$digest();
            shared.el = shared.$element[0];
            shared.$childScope = shared.$element.scope();
        };

    });

    describe('when compiled', function() {

        describe('when all parameters are provided', function() {

            beforeEach(function() {
                shared.$parentScope.someProp = {
                    a: 'a',
                    b: 'b'
                };
                shared.createDirective();
            });

            it('should have a render method', function() {
                expect(typeof shared.$childScope.render).toEqual('function');
            });

        });

    });

});

The job of the link function is to add a render method to the scope. It works in the application, but in Jasmine tests it never runs.

I've looked all over at various other questions listed below, but no luck.

Any help appreciated.

[1]

Community
  • 1
  • 1
Jamie Mason
  • 4,159
  • 2
  • 32
  • 42
  • Are you certain that is works in the application? I am pretty sure that the controller is invoked first before the link function. Thus, you're calling $scope.render before it was defined. – ryeballar Jun 25 '15 at 11:28
  • This is a reduced test case, but yes in the application it works — I may have a race condition though as the network is involved in the app. Looking into that, thanks. – Jamie Mason Jun 25 '15 at 11:29

1 Answers1

0

As pointed out by @aliasm2k, the issue here is that the controller is invoked before the link function.

Because the controller is calling $scope.render before the link function has created it, the call stack is abandoned and the link function is not run.

Jamie Mason
  • 4,159
  • 2
  • 32
  • 42