Parsing html data from an array inside an AngularJS view

February 16, 2015, 7:53 pm
Author: James Griffiths

There's no denying that AngularJS is a fantastic framework to develop with but if you're coming from a jQuery/traditional JavaScript background there are certain aspects of Angular based development you might initially struggle with.

One of those is parsing HTML strings within views using ng-repeat.

Oh...that wasn't supposed to happen!

Like most developer's you'll no doubt parse content retrieved from a database into custom objects and then loop through these to populate your page with the corresponding items of data.

Let's say you store strings of HTML in these objects (this could be for rendering pre-built external links for example), when AngularJS iterates through these with ng-repeat to populate your view you'll find that the HTML content renders as a string displaying the names of the tags.

So instead of something like this:

Heading content
Paragraph

You get the following instead:

<h2>Heading content</h2><p>Paragraph<p/>

Oops - definitely not what we want!

Panic not, help is at hand

One of the great things about AngularJS is the ability to use pre-defined filters or create your own filters as required.

A filter is defined, by the official AngularJS Docs, as follows:

A filter formats the value of an expression for display to the user. 
They can be used in view templates, controllers or services and it is easy to 
define your own filter.

Fairly straightforward stuff (and, if you've never used them before, filters are both incredibly powerful and flexible).

So, if we look at our original problem, we can define a custom filter to parse the HTML and render that as actual HTML content and NOT as HTML inside a string.

Here's how we might accomplish that:

.filter('renderHTMLCorrectly', function($sce)
{
	return function(stringToParse)
	{
		return $sce.trustAsHtml(stringToParse);
	}
});

We define a custom filter called renderHTMLCorrectly, passing in the HTML string as a parameter (stringToParse) that we want to 'approve' for use in our view and within the function we use the trustAsHtml method of the Strict Contextual Escaping service ($sce) to 'authorise' this string to render as HTML.

This custom filter could be contained in its own dedicated filters.js file (probably the better way to manage custom filters - intelligent organisation of code should always be a priority for the professional developer) which could then be included in your HTML page with the appropriate script tag call like so:

<script src="assets/js/custom/filters.js"></script>
<script src="assets/js/custom/factories.js"></script>
<script src="assets/js/custom/controllers.js"></script>
<script src="assets/js/custom/app.js"></script>

So that's the custom filter created and now available for use within our controllers, services or views but how to actually implement that inside the actual view template?

Simple - like most things in AngularJS:

<ul>
   <li ng-repeat="item in items">
      <div ng-bind-html="item.heading | renderHTMLCorrectly"></div>
      <div ng-bind-html="item.paragraph | renderHTMLCorrectly"></div>
   </li>
</ul>

Inside our view, within the ng-repeat directive, we can pass our custom filter - renderHTMLCorrectly - in to the ng-bind attribute to instruct AngularJS to render the iterated item as HTML content.

Although a simple use of filters in AngularJS that helps solve our problem with rendering HTML from string data inside loops within a view template.

Categories

« Return to Posts

Post a comment

All comments are welcome and the rules are simple - be nice and do NOT engage in trolling, spamming, abusiveness or illegal behaviour. If you fail to observe these rules you will be permanently banned from being able to comment.

Archive by Date