AngularJS logo ← Blog

Parsing HTML generated outside of Angular

It often happens that you have to work on some old project using jQuery. But in modern Web Development jQuery just doesn’t cut it. So you write new features in Angular. But sometimes you have to modify existing code.

It’s not a problem as long as HTML is static, but if it’s generated on server side Rails+jQuery style, then Angular won’t know anything about it when it arrives at the browser.

So we have to make Angular parse this HTML. I remember a long time ago when I first encountered that problem I googled quite a lot but came up empty handed. So I had to find a way myself. Recently my colleagues stumbled on the same problem so I decided to share this little piece of code on the internets.

var $injector = angular.element(document).injector() // first we get the injector our app uses
$injector.invoke(function ($rootScope, $compile) {
	// you inject anything here in params
	var element = angular.element("#selector") // get the element we want to parse
	// following hack isn't always necessary, but I use it to prevent double parsing if the same HTML is generated statically and dynamically
	if (element.attr("class") && element.attr("class").indexOf("ng-scope") != -1) {
		return
	}
	var compiled = $compile(element)($rootScope) // finally, we compile the element against root scope
	compiled.scope().$apply() // ... and we tell Angular that we made changes outside of its 'world'
})

Well… That’s pretty much it. You shouldn’t try running your angular app again. It’s going to create a separate application.

Also I want to share an interesting gotcha. If you inline your angular templates with

<script type="text/ng-template" id="the-template" >

and they are in dynamically generated HTML, you have to parse this HTML. Strangely enough Angular doesn’t use selectors to get this template. Rather, it puts this template into the template cache when it encounters it during parsing.