saruftw
saruftw

Reputation: 1164

$compile doesn't insert scope variable into the HTML

I want to test the rendering of an HTML with my scope variable inside my unit test.

HTML has 2 <textarea> which are as follows:

<textarea ng-model="a" ng-change="someFunction(a)" value={{a}}></textarea>
<textarea ng-model="b" ng-change="someFunction(b)" value={{b}}></textarea>

a and b are scope variables such that a = someFunction(b) and b=someFunction(a).

Explanation: Typing in a calls the function someFunction(a) which changes the text in the textarea b. Vice versa for b.

The unit test I've written are as follows:

    var compile,
        scope,
        tc,
        template,
        controller,
        httpGuy;

    beforeEach(inject(function($compile, $rootScope, $templateCache, $controller, $httpBackend) {
        scope = $rootScope.$new();
        controller = $controller('ABCController', {'$scope': scope});
        compile = $compile;
        template = $templateCache.get('app/index.html');
    }));

it('test1', function() {
            scope.a = SOME_VALUE;
            scope.someFunction(scope.a);
            // at this point scope.b  changes to correct value
            var html_template = compile(template)(scope); // this should insert the scope variables in html?
            scope.$digest();
            console.log(angular.element(html_template.find('textarea')[1]));
        });

The test gives the output of <textarea> with value="" i.e. empty. Value should have been rendered because we introduced the scope variables in the HTML. Why doesn't this happen?

Upvotes: 0

Views: 226

Answers (1)

Abhishek
Abhishek

Reputation: 1477

If the value of $scope.b in ABCController is not set, then the value will be ""(empty string).

Try setting some value for it in controller, the same value will be available to <textarea> element in unit test.

Here is the sample jsfiddle for the same

Trying to set some value to scope.a or scope.b inside a test case and then compiling wont insert the new assigned value to compiled dom, as the template will be having an ng-controller='ABCController', which creates an new and fresh instance of the controller(with different scope). Hence the value set on scope object will not be of any effect.

If you want to set some values to scope and then want to compile the template with a particular scope object, then remove ng-controller from template and use below pattern

var compile,
    scope,
    controller;

beforeEach(function() {
    module("ABCControllerModule"); // Instantiate the 'ABCController' module
    inject(function(_$compile_, _$rootScope_, _$controller_) {
      scope = _$rootScope_.$new();
      controller = _$controller_('ABCController', {'$scope': scope});
      compile = _$compile_;
    });
});

it('test1', function() {
    scope.a = SOME_VALUE;
    scope.someFunction = function(a) {
        ...
    };
    var html_template = compile(<template-with-out-ng-controller->)(scope);
    console.log(angular.element(html_template.find('textarea')[1]));
}); 

Upvotes: 1

Related Questions