Angular Trust Filter

It seems every Angular project I write, at some point, sees the error:

Attempting to use an unsafe value in a safe context.

This is because of Angular’s $sce service, which enabled by default:

SCE assists in writing code in way that (a) is secure by default and (b) makes auditing for security vulnerabilities such as XSS, clickjacking, etc. a lot easier.

Unfortunately, it can be cumbersome, especially when working with dynamic objects.

The View

Suppose you’re writing the front-end for a blog where the content is consumed via an AJAX request:

<h1 ng-bind-html="response.title"></h1>

<section ng-bind-html="response.content"></section>

When your view attempts to use the raw response content, you’ll get an error because it’s unsafe.

The Controller

To get around this, you can have your controller “whitelist” the content:

angular
  .module('example', [])
  .controller('ExampleController', [
    '$sce',
    '$scope',
    function($sce, $scope) {
      ...
      // Assume there's a previous `$http` response
      response['title']   = $sce.trustAsHtml(response['title']);
      response['content'] = $sce.trustAsHtml(response['content']);

      $scope.response = response;
    }
  ])
;

The Filter

Instead, create a trust filter.

angular
  .module('example', [])
  .filter('trust', [
    '$sce',
    function($sce) {
      return function(value, type) {
        // Defaults to treating trusted text as `html`
        return $sce.trustAs(type || 'html', text);
      }
    }
  ])
;

Now your view an simply read:

<h1 ng-bind-html="response.title | trust"></h1>

<section ng-bind-html="response.content | trust"></section>

As with all things Angular, your view will contain your rendering logic and your controllers can stay as thin as possible.