34

I am trying to insert HTML inside template using ng-bind-html-unsafe attribute. But for some reason its not working.

My code:

<tr class="white two-button" ng-repeat="(key,value) in recommendations | ojoScoreFilter:ojoScore | relevancyScoreFilter:relevancyScore | orderBy:predicate:reverse">
<td>
<div ng-bind-html-unsafe="value.button"></div>
</td>
</tr>

I am not able to see the HTML. If I change ng-bind-html-unsafe="value.button" to ng-bind-html-unsafe="{{value.button}}" then it shows HTML but within the attribute, something like this:

<div ng-bind-html-unsafe="&lt;a class=&quot;action_hrefs full-width bgcolor10 purple-hover flat-button flat-white-button btn&quot; data-value=&quot;947&quot; href=&quot;#&quot;&gt;&lt;i class=&quot;fa fa-lock&quot;&gt;&lt;/i&gt;&nbsp;Unlock&lt;/a&gt;"></div>
Niraj Chauhan
  • 7,677
  • 12
  • 46
  • 78

2 Answers2

122

Ok I found solution for this:

JS:

$scope.renderHtml = function(html_code)
{
    return $sce.trustAsHtml(html_code);
};

HTML:

<p ng-bind-html="renderHtml(value.button)"></p>
Niraj Chauhan
  • 7,677
  • 12
  • 46
  • 78
  • 6
    Woah this is the only one that worked! I've tried everything, thank you :) – anpatel Mar 25 '14 at 16:23
  • 14
    This is the only solution that worked for me as well. Be sure to inject $sce into your controller. – Erik Olson May 08 '14 at 18:24
  • 1
    This works, but seems a bit overkill. I have to inject $sce into every controller? And have to add that `renderHtml` function to every controller that needs html? – Andrew Gee Jul 02 '14 at 13:19
  • 2
    This is the only solution that worked for me too. The accepted answer found in this other SO post: http://stackoverflow.com/questions/9381926/insert-html-into-view-using-angularjs did NOT work. – TMc Jul 17 '14 at 14:22
  • 14
    In order for this to work, make sure to inject $sce into the function defined in the controller, something like this: `myApp.controller('myCtrl', function($scope, $sce) {` – Devner Nov 11 '14 at 11:20
  • 1
    This really worked for me and to help @AndrewGee, instead to add the $sce on all controllers, you just make it available on your main controler like $scope.$sce = $sce ... doing this, you can just call $scope.$sce anywhere you want, because, this is already available and exposed on your scope. – Paulo Griiettner Jan 11 '15 at 08:10
  • 1
    Another smart thing to do... is to add $scope.renderHtml on your main scope with $id 002... and just call this function any time you need – Paulo Griiettner Jan 11 '15 at 08:12
  • @Griiettner can you elaborate on that? – daniel0mullins Oct 29 '15 at 17:36
  • It's already been mentioned the $sce service needs to be invoked by the controller, i.e.: `myApp.controller('myCtrl', ['$scope', '$sce', function($scope, $sce) { /* ... */ }]);` but, to be clear: you also need to include the `ngSanitize` module in your javascript on the page and in your app declaration: `myApp = angular.module('myApp', ['ngSanitize','myCtrl']);` – DrewT Feb 01 '16 at 22:17
14

make a filter like this

.filter('trusted',
   function($sce) {
     return function(ss) {
       return $sce.trustAsHtml(ss)
     };
   }
)

and apply this as a filter to the ng-bind-html like

<div ng-bind-html="code | trusted">
Ruben Decrop
  • 1,979
  • 1
  • 17
  • 9
  • 1
    The accepted answer above got a lot of votes but I think this solution is a better answer. Doing it this way will solve the issue of having to inject $sce into every controller that will display html. I'm still new at this though, so feel free to correct me! – Jubskie Aug 03 '16 at 09:05