1

I'm working with a legacy VB.Net app I inherited. The ng-app and ng-controller directives both appear on the HTML element in the root master page:

<html runat="server" id="html" ng-controller="MasterController">

The ng-app attribute is set in the code-behind for the page. It's present when I run the page and view the source. The app is scoped to the module ng-app="myModule"

The controller is defined in a function passed to add_load in the masterpage also, not quite at the end of the body, but not far from it:

Sys.Application.add_load(function () {

        var module = angular.module('myModule');
        var MasterController = function ($scope, $compile) {
            ... // stuffs
            }
        };

        module.controller('MasterController', ["$scope", "$compile", MasterController]);

    });

Locally, this works (or seems to work) fine, I see no errors in the console. However, the app has now been deployed to a staging environment, and in the browser console in that environment I see an Angular error:

[ng:areq] not a function got undefined

There are very few differences between the staging area and my local environment, these differences are largely that the .Net script bundler is used to concatenate and minify a bunch of JS files, including Angular, and the data used by the app. AFAIK there are no other differences.

I don't think the bundler is causing the issue as I enabled bundling locally and I don't see the error. I also can't see that the data passed to the app is causing the problem (it's customer data, account data, etc) as it's not even used in this particular controller.

1 Answer 1

2

Don't use function expression syntax since the variable can be called before it is assigned. Use function declaration syntax instead per the best practices guide.

In addition, since you are passing a function reference, pull out the inject piece altogether to ensure that your code is minification safe.

var module = angular.module('myModule');
function masterController($scope, $compile) {
    ... // stuffs
}

masterController.$inject = ["$scope", "$compile"];

module.controller('MasterController', masterController);
Sign up to request clarification or add additional context in comments.

7 Comments

Thanks for the tips! The style guide looks great. I will try these asap
Still do not understand why this is best practice. Why splitting 1 logical line that declares controllers function into 3 lines is so smart idea...
@PetrAveryanov because Angular 1.x dependency injection uses string matching and/or the array syntax "hack" that was added later (version 1.2 perhaps?). By pulling it out explicitly, you are ensuring that your code is dependency safe AND it is explicit and very readable. Any subsequent developer will know EXACTLY what this code is doing. In addition, how many controllers end up growing to inject 10 arguments? That makes for a very long "one-liner". Breaking it apart makes it easier to control and read your declaration.
I was under the impression that module.controller('MasterController', ["$scope", "$compile", MasterController]); was minification-safe, I thought that was the point of the array. But I totally see that the code is more readable using the $inject pattern
This is logically 'atomic' operation. I want to define controller. You can not comment any of that lines independently, You can not change $compile to $parse in one line only. So why should i split it?
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.