Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error: Unknown provider: aProvider <- a

I'm using AngularJS in a Ruby on Rails 3.2.8 project with assets.

When I load up my form which is using AngularJS on my development machine I don't have a problem. However when I load the same form up on my production server I get this error in the Javascript console:

Error: Unknown provider: aProvider <- a

I've tracked it back to my coffeescript file where I setup AngularJS for use within a form:

$ (event) ->
  $("#timesheet_description").autocomplete({source: '/autocomplete/work_descs'})

  # Create AngularJS module
  app = angular.module 'timesheetApp', []

  # Create a AngularJS controller
  app.controller "TimesheetCtrl", ($scope) ->
    $scope.costed_amount = 0
                                                                                                # Bind my module to the global variables so I can use it.
  angular.bootstrap document, ["timesheetApp"]  

If I comment all this out the page will load without errors and without AngularJS abilities.

Is the problem due to Rails assets compiling and minify? Is there a way to fix this and still use coffeescript and Rails assets?

like image 887
map7 Avatar asked Oct 17 '12 04:10

map7


2 Answers

AngularJS, when using the style you're using right now (called pretotyping), uses the function argument names to do dependency injection. So yes, minification does break this completely.

The fix is simple, though. In every case where you need injection (are using '$xxx') variables, do this:

app.controller "TimesheetCtrl", ['$scope', ($scope) ->
  $scope.costed_amount = 0
]

Basically, replace all function definitions with an array. The last element should be the function definition itself, and the first ones are the $names of the objects you want injected.

There's some more (albeit not clear enough) info on the docs.

like image 158
Sudhir Jonathan Avatar answered Oct 11 '22 21:10

Sudhir Jonathan


If you miss the array notation somewhere , to locate this we need to modify the angular code little bit, but its very quick solution.

change is console.log("Array Notation is Missing",fn); ( line no 11 from function start)

Find out annotate function in angular.js (non-minified)

function annotate(fn) {
      var $inject,
          fnText,
          argDecl,
          last;

      if (typeof fn == 'function') {
        if (!($inject = fn.$inject)) {
          $inject = [];
          if (fn.length) {
console.log("Array Notation is Missing",fn);
fnText = fn.toString().replace(STRIP_COMMENTS, '');
        argDecl = fnText.match(FN_ARGS);
        forEach(argDecl[1].split(FN_ARG_SPLIT), function(arg){
          arg.replace(FN_ARG, function(all, underscore, name){
            $inject.push(name);
          });
        });
      }
      fn.$inject = $inject;
    }
  } else if (isArray(fn)) {
    last = fn.length - 1;
    assertArgFn(fn[last], 'fn');
    $inject = fn.slice(0, last);
  } else {
    assertArgFn(fn, 'fn', true);
  }
  return $inject;
}
like image 31
Deepak Patil Avatar answered Oct 11 '22 23:10

Deepak Patil