ngBindHtml with $sce: error testing $compile

1,352 views
Skip to first unread message

Daniel Neugebauer

unread,
Oct 29, 2013, 1:40:48 PM10/29/13
to ang...@googlegroups.com
Hi!

I'm trying to test rendering of a template that uses the ngBindHtml
directive with $sce.trustAsHtml, version is AngularJS 1.2.0-rc3. Running
the test (Karma, Jasmine) always results in:

Error: [$sce:itype] Attempted to trust a non-string value in a
content requiring a string: Context: html
http://errors.angularjs.org/1.2.0-rc.3/$sce/itype?p0=html


What the controller does: (boxes[i].text contains HTML code that should
be used as-is on output)

for (var i=0; i<$scope.boxes.length; i++) {
$scope.boxes[i].text = $sce.trustAsHtml($scope.boxes[i].text);
}


The template defines:

<div ng-bind-html="box.text" ng-if="box.text"></div>


Test:

var scope = {};
var $httpBackend, $sce, $rootScope, $compile, HomepageCtrl;

beforeEach(inject(function($injector, $controller, _$sce_,
_$rootScope_, _$compile_){
HomepageCtrl = $controller('HomepageCtrl', {
'$scope': scope
});

$rootScope = _$rootScope_;
$sce = _$sce_;
$compile = _$compile_;

// stripped test setup of $httpBackend, returning a deep copy
// of dummyBoxData to the controller
}));

it('should display all boxes', function(){
$httpBackend.flush();
var compiled =
$compile(window.__html__['templates/pages/homepage.html'])($rootScope);
$rootScope.$digest();
$httpBackend.flush();

var jHighlightBoxes = jQuery('.highlight-box', compiled);
expect(jHighlightBoxes.length).toBe(dummyBoxData.length);
});


Stack trace: (paths shortened, run on non-minified AngularJS)

Error: [$sce:itype] Attempted to trust a non-string value in a content
requiring a string: Context: html
http://errors.angularjs.org/1.2.0-rc.3/$sce/itype?p0=html
at angular.js:78:12
at trustAs (angular.js:11318:15)
at Object.sce.(anonymous function) [as trustAsHtml]
(angular.js:12067:16)
at main.js:16:41
at angular.js:6672:11
at wrappedCallback (angular.js:9769:81)
at wrappedCallback (angular.js:9769:81)
at angular.js:9855:26
at Scope.$eval (angular.js:10699:28)
at Scope.$digest (angular.js:10547:31)

Error: [$rootScope:inprog] $digest already in progress
http://errors.angularjs.org/1.2.0-rc.3/$rootScope/inprog?p0=%24digest
at angular.js:78:12
at beginPhase (angular.js:10995:15)
at Scope.$digest (angular.js:10538:9)
at Function.$httpBackend.verifyNoOutstandingExpectation
(angular-mocks.js:1462:16)
at null.<anonymous> (mainTest.js:46:26)

main.js:16 is the call to $sce.trustAsHtml from above,
mainTest.js:46 is $httpBackend.verifyNoOutstandingExpectation() in
afterEach().


The error is being caused by the call to $compile(). Do I need to call
some other function, maybe pass in a local scope and/or the already
instantiated HomepageCtrl to $compile? Am I using $sce correctly? Is
there any example of how to test compilation of a template that uses
ngBindHtml with trusted $sce data?

Compilation with ngBind instead of ngBindHtml and without calling $sce
in my controller works fine (console.log logs the expected output except
I don't get trusted HTML output for boxes.text).

Thanks,
Daniel
Reply all
Reply to author
Forward
0 new messages