68

This is my template:

<div class="span12">
  <ng:view></ng:view>
</div>

and this is my view template:

<h1>{{stuff.title}}</h1>

{{stuff.content}}

I am getting the content as html and I want to display that in a view, but all I am getting is raw html code. How can I render that HTML?

7
  • 2
    Where is the HTML coming from? Under different circumstances, you'll want ngBindHtmlUnsafe, ngSanitize, or a custom directive. Commented Apr 2, 2013 at 1:14
  • The html is coming from my database Commented Apr 2, 2013 at 1:37
  • 1
    Is the content absolutely trusted? Commented Apr 2, 2013 at 1:41
  • 1
    For example, if the HTML contains a script tag the browser would execute it. This type of "injection" attack is a common way of damaging apps and stealing user data. AngularJS has a separate module called ngSanitize that you can use to strip the HTML of any dangerous tags; it also has a directive called ngBindHtml that works just like ngBindHtmlUnsafe, but strips the dangerous tags for you. If the content is entirely yours - and doesn't come from users or third parties - then you don't need it. Commented Apr 2, 2013 at 3:45
  • 1
    possible duplicate of Insert HTML into view using AngularJS
    – kontur
    Commented Oct 3, 2014 at 13:42

5 Answers 5

100

Use-

<span ng-bind-html="myContent"></span>

You need to tell angular to not escape it.

7
  • 10
    API has changed in AngularJS 1.2. stackoverflow.com/questions/18340872/…
    – Alex M
    Commented Dec 4, 2013 at 18:00
  • 2
    amccausl has saved new angular users countless hours of debugging due to angular "hell docs", ng-bind-html-unsafe is deprecated and please refer to the link located in the comment above to solve the answer.
    – rjm226
    Commented Dec 16, 2013 at 22:28
  • 1
    I just inserted <span ng-bind-html="myHtmlFragment"></span> into my template and without doing anything else it worked great. I didn't have to inject $sce. Here's the docs: docs.angularjs.org/api/ng/directive/ngBindHtml Commented Feb 9, 2015 at 20:47
  • 1
    ngSanitize -one thing that was missing for me when using the answers here(you can get from the angular docs on ng-bind-html) is you need to make sure your app includes the ngSanitize module. Without that it did not work.
    – jamie
    Commented Aug 11, 2015 at 22:06
  • 1
    ng-bind-html alone worked, without using trustAsHtml Commented Aug 8, 2017 at 8:04
50

To do this, I use a custom filter.

In my app:

myApp.filter('rawHtml', ['$sce', function($sce){
  return function(val) {
    return $sce.trustAsHtml(val);
  };
}]);

Then, in the view:

<h1>{{ stuff.title}}</h1>

<div ng-bind-html="stuff.content | rawHtml"></div>
3
  • 1
    This is an excellent solution @Daniel. If I am using the $sce.trustAsHtml, I dont need to include the ngSanitize dependency to the app module? I am using Angular 1.3
    – Neel
    Commented Jun 23, 2015 at 6:34
  • Can we use ng-include to achieve this? Commented Sep 26, 2015 at 15:13
  • this does not work for me, i am using angular 7. Kindly suggest the solution. Thanks.
    – Kamlesh
    Commented Apr 6, 2019 at 9:25
4

In angular 4+ we can use innerHTML property instead of ng-bind-html.

In my case, it's working and I am using angular 5.

<div class="chart-body" [innerHTML]="htmlContent"></div>

In.ts file

let htmlContent = 'This is the `<b>Bold</b>` text.';
0
3

You shoud follow the Angular docs and use $sce - $sce is a service that provides Strict Contextual Escaping services to AngularJS. Here is a docs: http://docs-angularjs-org-dev.appspot.com/api/ng.directive:ngBindHtmlUnsafe

Let's take an example with asynchroniously loading Eventbrite login button

In your controller:

someAppControllers.controller('SomeCtrl', ['$scope', '$sce', 'eventbriteLogin', 
  function($scope, $sce, eventbriteLogin) {

    eventbriteLogin.fetchButton(function(data){
      $scope.buttonLogin = $sce.trustAsHtml(data);
    });
  }]);

In your view just add:

<span ng-bind-html="buttonLogin"></span>

In your services:

someAppServices.factory('eventbriteLogin', function($resource){
   return {
        fetchButton: function(callback){
            Eventbrite.prototype.widget.login({'app_key': 'YOUR_API_KEY'}, function(widget_html){
                callback(widget_html);
            })
      }
    }
});
2

So maybe you want to have this in your index.html to load the library, script, and initialize the app with a view:

<html>
  <body ng-app="yourApp">
    <div class="span12">
      <div ng-view=""></div>
    </div>
    <script src="http://code.angularjs.org/1.2.0-rc.2/angular.js"></script>
    <script src="script.js"></script>
  </body>
</html>

Then yourView.html could just be:

<div>
  <h1>{{ stuff.h1 }}</h1>
  <p>{{ stuff.content }}</p>
</div>

scripts.js could have your controller with data $scope'd to it.

angular.module('yourApp')
    .controller('YourCtrl', function ($scope) {
      $scope.stuff = {
        'h1':'Title',
        'content':"A paragraph..."
      };
    });

Lastly, you'll have to config routes and assign the controller to view for it's $scope (i.e. your data object)

angular.module('yourApp', [])
.config(function ($routeProvider) {
  $routeProvider
    .when('/', {
      templateUrl: 'views/yourView.html',
      controller: 'YourCtrl'
    });
});

I haven't tested this, sorry if there's a bug but I think this is the Angularish way to get data

2
  • What if I want this same behavior but not depend on routeProvider? Commented Jul 1, 2016 at 2:18
  • It's the same using ui-router, only it's $stateProvider instead of $routeProvider and .state( 'yourState', { url:'/', templateUrl: 'yourView.html', controller: 'YourCtrl' });
    – irth
    Commented Jul 1, 2016 at 23:17

Not the answer you're looking for? Browse other questions tagged or ask your own question.