How am I supposed to pass data from serverside controller an AngularJS controller?

Ben Aaronson picture Ben Aaronson · Mar 8, 2014 · Viewed 12.3k times · Source

I've encountered what I believe to be a common scenario, in which I am using an MVC pattern (specifically ASP.NET's MVC framework) for a web application, with AngularJS on the front-end. My problem is that I have a particular value which is part of the model getting passed to my view, which I also want to make available to my Angular controller's $scope, ideally as soon as the controller is initialized.

How to do this is a question that has been asked and answered before. There's an obvious candidate for it: ngInit. However, at some point Angular updated their documentation with what appears to be a warning against this specific thought:

The only appropriate use of ngInit is for aliasing special properties of ngRepeat, as seen in the demo below. Besides this case, you should use controllers rather than ngInit to initialize values on a scope.

The suggested alternative isn't very relevant.

Of course, there are other workarounds I can think of. The view could insert the value into an ngModel directive on a hidden input, for example. Or I could just plain ignore the warning and use ngInit anyway. But any that I can think of are either an uglier way of doing the same thing as ngInit, or clearly worse.

Ultimately the fact that what seems like the obvious solution to me is apparently the wrong one is probably an indicator that my mindset isn't in tune with how Angular is supposed to be done. So my question isn't "how do I deal with this scenario", instead it's:

  1. How am I supposed to deal with, or avoid, this scenario?
  2. Why am I not supposed to use ngInit?

A clarification, since from the first two comments this isn't clear: This is for a situation where some or most of the page is being served directly as the MVC view, with only some particular piece of functionality being provided by Angular. The data that I want to pass to my Angular controller is already passed to the view in the model. I don't want the Angular controller to then go and have to do its own get request to the server just to get the same parameter that's already available to the view in a different format.

Answer

Matty J picture Matty J · Sep 5, 2014

You should pass it from your server side controller to your AngularJS controller by using either a 'value' or 'constant' provider, as described here: https://docs.angularjs.org/guide/providers

For example, you could do something like the following:

<script>
    angular.module("hobbitModule").value("companionship", @Html.Raw(Model));
</script>

and then inject it in to your controller

var module = angular.module("hobbitModule");
module.controller("CompanionshipController", function($scope, companionship) {
    $scope.companions = companionship;
});

as described in this article: http://blog.mariusschulz.com/2014/03/25/bootstrapping-angularjs-applications-with-server-side-data-from-aspnet-mvc

If you think it may become more complicated that just a value, you could use a Service provider and inject that instead of the value provider.