3 ways to get backend data to AngularJS

Tags:

It seems this is a rather common conundrum with Angular code: You have some backend data, say in PHP or Rails, and you want to output it when rendering the page so that Angular can display it.

Since Angular is designed to work more as a single-page app framework, it isn’t immediately obvious how to do this without Ajax, so here I’ll present three ways you can do it.

1. Using ng-init

This is probably the single most straightforward way to do it. Simply stick an ng-init attribute to some element and that’s all.

<div ng-controller="FooCtrl">
  <span ng-init="hello = true">something</span>
</div>

This example would set $scope.hello to true

However, this is not always a suitable option: Since the data goes into an element’s attribute, it can be difficult to do correctly if you need to assign values other than numbers or booleans.

So, ng-init is best used with simple values.

2. Using a global variable

This may actually be even more straightforward than the above option, and is probably the simplest choice if you need to set strings or objects which can be difficult to get working correctly with ng-init

Simply store your data in a global variable (or a namespaced variable) and access it directly from your controller:

var stuff = { hello: 'foobar' };
 
function FooCtrl($scope) {
  $scope.hello = stuff.hello;
}

However, as you might know, globals aren’t exactly a great solution for various reasons.

I would not recommend using this approach unless you’re doing an extremely trivial application. Otherwise it can lead to confusion about what the variables are used for, as often your global would be defined away from your controller code, and all the other issues which globals generally have.

3. Using module.value

This is my recommended approach: Use module.value to assign the data into the module.

For example,

var myModule = angular.module('example', []);
 
myModule.value('stuff', { hello: 'foobar' });
 
myModule.controller('FooCtrl', function($scope, stuff) {
  //the 'stuff' value we created before the controller is
  //automatically injected by Angular's DI system
});

This approach uses Angular’s own dependency injection mechanics to get the data to where it needs to be. You can define as many controllers or services and simply declare your value’s name as a dependency and it will get automatically injected to it. Doesn’t get much simpler than that!

And as an added benefit, this can be leveraged in testing to mock out the value easily.

In closing

So, approaches 1 and 3 are really the ones I would recommend using. #2 can be used for trivial code, but I would recommend avoiding it since often the case for trivial code is it ends up becoming non-trivial very fast :)

Do you have any other solutions to this? What is your favorite way to solve this, and why?