0

I have a SPA application working perfectly so far. It had been developed in JavaScript using AngularJS (+ other libs).

Now, I want to minify the scripts and I'm testing both yuicompressor and Google's compiler.

As soon as I deploy the minified version of the script and test it, I get an error.

The JavaScript file prior to minifying is:

var MyApp_Sim_Web = angular.module( 'MyApp_Sim_Web', ['ngRoute' , 'ngSanitize']) ;


//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------  $routeProvider  ------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------


    MyApp_Sim_Web.config(function($routeProvider) {

        $routeProvider

            .when ('/Login', {
                templateUrl: 'Pages/Login.html' ,
                controller:  'LoginController'
            })

            .when ('/', {
                templateUrl: 'Pages/Login.html' ,
                controller:  'LoginController'
            })
            .when ('/User_Main', {
                templateUrl: 'Pages/User_Main.html' ,
                controller:  'UserController'
            })
            .otherwise({ redirectTo: '/' });

    });

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------  $IndexController  ----------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------

    MyApp_Sim_Web.filter('Make_Timestamp_Readable', function() {
        return function(input) {
            var date    = new String(input),
                year    = date[ 0] + date[ 1] + 
                          date[ 2] + date[ 3]   ,
                month   = date[ 4] + date[ 5]   ,
                day     = date[ 6] + date[ 7]   ,
                hour    = date[ 8] + date[ 9]   ,
                minute  = date[10] + date[11]   ,
                seconds = date[12] + date[13]     ;

            var reformattedDate = year + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + seconds;

            var newDate = new Date(reformattedDate);

            return newDate;
        };
    });

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------  $IndexController  ----------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------

MyApp_Sim_Web.controller('IndexController' , ['$rootScope' , '$scope' , '$log' , '$location' , '$sce' , 'DB_Services' , function( $rootScope , $scope , $log , $location , $sce , DB_Services ) {


        // Following declaration is aimed to enable access to DB from any controller.

        $rootScope.Handle_DB_Request = function(p_Query , p_Callback) {
            DB_Services(p_Query).then(function(d) {

                p_Callback(d) ;
            });
        };            

} ]) ;

The minified version using yuicompressor is:

var MyApp_Sim_Web=angular.module("MyApp_Sim_Web",["ngRoute","ngSanitize"]);MyApp_Sim_Web.config(function(a){a.when("/Login",{templateUrl:"Pages/Login.html",controller:"LoginController"}).when("/",{templateUrl:"Pages/Login.html",controller:"LoginController"}).when("/User_Main",{templateUrl:"Pages/User_Main.html",controller:"UserController"}).otherwise({redirectTo:"/"})});MyApp_Sim_Web.filter("Make_Timestamp_Readable",function(){return function(g){var a=new String(g),e=a[0]+a[1]+a[2]+a[3],d=a[4]+a[5],f=a[6]+a[7],c=a[8]+a[9],b=a[10]+a[11],i=a[12]+a[13];var j=e+"-"+d+"-"+f+" "+c+":"+b+":"+i;var h=new Date(j);return h}});MyApp_Sim_Web.controller("IndexController",["$rootScope","$scope","$log","$location","$sce","DB_Services",function(b,d,e,f,c,a){b.Handle_DB_Request=function(h,g){a(h).then(function(i){g(i)})}}]);

and the same using Google's compiler is:

var MyApp_Sim_Web=angular.module("MyApp_Sim_Web",["ngRoute","ngSanitize"]);MyApp_Sim_Web.config(function(a){a.when("/Login",{templateUrl:"Pages/Login.html",controller:"LoginController"}).when("/",{templateUrl:"Pages/Login.html",controller:"LoginController"}).when("/User_Main",{templateUrl:"Pages/User_Main.html",controller:"UserController"}).otherwise({redirectTo:"/"})});
MyApp_Sim_Web.filter("Make_Timestamp_Readable",function(){return function(a){a=new String(a);return new Date(a[0]+a[1]+a[2]+a[3]+"-"+(a[4]+a[5])+"-"+(a[6]+a[7])+" "+(a[8]+a[9])+":"+(a[10]+a[11])+":"+(a[12]+a[13]))}});MyApp_Sim_Web.controller("IndexController",["$rootScope","$scope","$log","$location","$sce","DB_Services",function(a,d,e,f,g,b){a.Handle_DB_Request=function(a,c){b(a).then(function(a){c(a)})}}]);

The error I get (Chome's console) is:

[$injector:modulerr] http://errors.angularjs.org/1.4.0-rc.1/$injector/modulerr?p0=PayPlus_Sim_We…2F%2F127.0.0.1%3A59561%2FPublic_Libs%2FAngular%2Fangular.min.js%3A39%3A416)

It is quite strange since, as stated, without the minification the application works perfectly (no error at all of any kind in console).

Does anyone have any idea what is going on?

Thanks in advance.

FDavidov
  • 3,505
  • 6
  • 23
  • 59
  • `MyApp_Sim_Web.config(function($routeProvider) {` ==> `MyApp_Sim_Web.config(['$routeProvider', function($routeProvider) {` – Tushar May 24 '16 at 07:13
  • The answers provide the solution but don't explain why. Angular's dep system hacks up named arguments by parsing `.toString()` from the function. It then uses the physical argument names in your function definition to look up the dep. When you minify it renames function arguments meaning angular tries to look for a dependency that doesn't exist. Using the array notation aliases it, so angular looks for deps by the array value not argument name. So every where you inject something you should use the array notation. – ste2425 May 24 '16 at 07:28
  • Thank you very much @ste2425 for the explanation. Unfortunately, it is not possible to VOTE for a comment, otherwise I would. – FDavidov May 24 '16 at 08:53

3 Answers3

2

Do exactly like you injected dependencies on your controller:

MyApp_Sim_Web.controller('IndexController' , ['$rootScope' , '$scope' , '$log' , '$location' , '$sce' , 'DB_Services' , function( $rootScope , $scope , $log , $location , $sce , DB_Services )

In your config:

MyApp_Sim_Web.config(['$routeProvider',function($routeProvider) {

}
geckob
  • 7,680
  • 5
  • 30
  • 39
  • Thank you @geckob for your prompt and correct answer. It solved the problem (somehow I missed the fact that I was not injecting this dependency correctly). – FDavidov May 24 '16 at 08:52
  • @FDavidov: No problem. I think both ways works fine. But if you need to minify, you need to do this way due to the way AngularJS DI works. It implicitly injected from the function parameter names which will mess up when it gets minified since it will change the name to be something else shorter – geckob May 24 '16 at 09:02
1

You should replace

MyApp_Sim_Web.config(function($routeProvider) {

with :

MyApp_Sim_Web.config(['$routeProvider',function($routeProvider) {

I had the same error a while back, read this for more info https://stackoverflow.com/a/37197114/4937709

Community
  • 1
  • 1
younes sofiane
  • 441
  • 1
  • 8
  • 22
1

This is a built-in problem in Angular. The "solutions" are discussed here.

Michael Lorton
  • 43,060
  • 26
  • 103
  • 144