Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS jasmine isolateScope() returns undefined

I'm expecting to get something from isolated scope out of my help-button directive.

  it('should contain proper scope, depending on attributes', function() {

        var el = compile('<help-button context-id="1"></help-button>')(scope);
        scope.$digest();


        console.log("el: " + el);
        console.log('Isolated scope: ' + el.isolateScope());
   ..
   });

-- before each test it does

beforeEach(inject(function($compile, $rootScope, $injector) {

    compile = $compile;
    scope = $rootScope.$new(); ...

it prints:

'el: [Object Object]'
'Isolated scope: undefined'

The question is: why I'm getting back undefined? Even if there is nothing in isolated scope, it still should be empty {} object. But anyway - the test is wrong - it does not show the isolated scope which (in real) contains data in there.

like image 815
ses Avatar asked Oct 28 '14 18:10

ses


2 Answers

I'm stupid.

But will reply to my own question because "a stupid is as stupid does" - i.e. may be one once would do the same (or for myself from the future).

The problem was in my helpbutton.html which my directive is using (which I did not show/mention in this question).

So that templateUrl were referring to helpbutton.html file that is supposed to be compiled to html properly.

Once I looked at el.html()'s output I got that it was not properly rendered (there were some missing tag or something).

Thant's why I could not get any scope from the element.

(though would be nice to have some kind of exception on the log if a template was not rendered properly to html)

like image 105
ses Avatar answered Oct 04 '22 12:10

ses


Just bumped into the same problem, but with a different cause. Just in case anyone else has the same issue, and this is probably really obvious once you've seen it before, but still.

If you are using a templateUrl, then the .isolateScope() function will return undefined until you've actually called .$digest and $httpBackend.flush();

When you use a template directly from the directive, it will be available the moment you do $compile(element)(scope).

This can come as a surprise if you've just changed a directive to use a templateUrl, or changed it from regular to isolateScope.

        responseHtml = '<div></div>';
        $httpBackend.expectGET('template.html').respond(200, responseHtml);

        var html = '<widget></widget>';
        element = angular.element(html);
        var compiled = $compile(element)(scope);

        console.log(element.isolateScope()); // undefined

        $rootScope.$digest();

        console.log(element.isolateScope()); // undefined

        $httpBackend.flush();

        console.log(element.isolateScope()); // now it will be available
like image 25
Erik Avatar answered Oct 04 '22 13:10

Erik