I recently created an AngularJS 1.0.0rc8 app with a Rails 3.2.3 back-end and it worked fine in development, but after deploying to Heroku there was a Unknown Provider error - apparently the app could not see the service object.
I know that it's now necessary to include angular-resource.js as a separate file and inject ngResource into the app module like this:
// main app javascript file
'use strict';
angular.module('contactapp', ['ngResource']).
config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/contacts', {template: 'assets/app/partials/contact-list.html', controller: ContactListCtrl}).
when('/contacts/new', {template: 'assets/app/partials/new-contact.html', controller: ContactListCtrl}).
when('/contacts/:contact_id', {template: 'assets/app/partials/contact-detail.html', controller: ContactDetailCtrl}).
otherwise({redirectTo: '/contacts'});
}]);
I also know that when files are minified that the controllers can't tell what their dependencies are unless they are also injected into the controller objects like this:
ContactListCtrl.$inject = ['$scope', '$http', 'Contacts'];
I've also tried doing it the other way that Angular recommends with bracket notation and passing in a function like this:
var ContactListCtrl= ['$scope', '$http', 'Contacts', function($scope, $http, Contacts) { /* constructor body */ }];
However, none of this seems to work.
The only way my application could see the resource provided was by turning off asset compression in the Production.rb file, like this:
# Compress JavaScripts and CSS
config.assets.compress = false
It took several hours for me to figure this out, but I recently saw another Rails + AngularJS app that had the same issue.
Jens Krause came to the same conclusion and explains it on his blog: http://www.websector.de/blog/2012/01/17/fun-with-angularjs-rails-coffeescript-sass-another-cafe-townsend-example/
If I have a relatively large app, and I need to compress the assets, how do I get around this using Angular with Rails?
Thanks.
If you're using Rails 4, change your js_compressor
in your production and staging environments to:
config.assets.js_compressor = Uglifier.new(mangle: false)
I think the problem is that your minifier is still obfusticating the variable name of the control itself (ContactListCtrl -> a or whatever it does).
Have you tried defining your controllers with the module.controller function?
angular.module('myModule', [])
.controller('Controller1', ['dep1', 'dep2', function(dep1, dep2) {
//code
}]);
Adding this line to my config/environments/production.rb did the trick for me:
config.assets.js_compressor = Sprockets::LazyCompressor.new { Uglifier.new(:mangle => false) }