I have and angularjs app.I want to concatenate all the JS files to a single file.I'm currently trying to use Grunt.js to setup an automatic build process for concatenating JavaScript files.
However my app runs without any error before concatenation.But after concatinating the files my app throws Error: $injector:modulerr
Module Error.
Below is my code after minification
angular.module('myApp', []);
var app = angular
.module('myApp', [
'ngRoute'
]);
app.config(function ($routeProvider) {
'use strict';
$routeProvider
.when('/', {
templateUrl: 'views/main.html',
controller: 'mainCntrl'
})
.when('/about', {
templateUrl: 'views/about.html',
controller: 'aboutCntrl',
controllerAs: 'about'
})
.otherwise({
redirectTo: '/'
});
});
app.controller('mainCntrl',['$scope', function ($scope) {
'use strict';
this.awesomeThings = [
'HTML5 Boilerplate',
'AngularJS',
'Karma'
];
}]);
app.controller('aboutCntrl',['$scope', function ($scope) {
'use strict';
this.awesomeThings = [
'HTML5 Boilerplate',
'AngularJS',
'Karma'
];
}]);
Any help appreciated.Thanks :)
You need to strictly follow either Inline Array Annotation of DI or $inject Property Annotation while minifying js files.
app.config(function ($routeProvider) {
'use strict';
//code
});
should be changed to below code.
Inline Array Annotation
app.config(['$routeProvider', function ($routeProvider) {
'use strict';
//code as is
}]);
$inject Property Annotation
var config = function($routeProvider) {
'use strict';
//code as is
}
config.$inject = ['$routeProvider'];
app.config(config);
Seems like the config line is your problem, try app.config(['$routeProvider', function ($routeProvider) { ... }]);
Yes, your annotation is not right. It should be
app.config(['$routeProvider', function ($routeProvider) {
'use strict';
//code
}]);
Use ng-annotate as a safe, clean and simple solution.
What it does is that when you grunt it'll annotate your definitions the proper way, so you don't have to deal with Angular's quirky way.
Run ng-annotate on
app.config(function($routeProvider) {
'use strict';
//code
});
and it'll auto-complete it for minification:
app.config(["routeProvider", function($routeProvider) {
'use strict';
//code
}]);
You can also add another step to your build workflow - grunt-ng-annotate in that case you will be able to skip almost all strict DI annotations. With this plugin you can simplify services/controllers definitions e.g.:
app.controller('mainCntrl', function ($scope) {
'use strict';
this.awesomeThings = [
'HTML5 Boilerplate',
'AngularJS',
'Karma'
];
});
It is extremely helpful when you heave a long list of services to inject into controller or another service. You don't have to remember to put each dependency twice.
Related
I'm struggling with this unknown provider error and just wondering what I'm doing wrong. Have this structure:
in main.js
'use strict';
angular.module('myApp')
.controller('MainCtrl', ['navService', function (navService) {
this.awesomeThings = [
'HTML5 Boilerplate',
'AngularJS',
'Karma'
];
this.active = false;
navService.getPosition();
}]);
In index html I have ng-controller="MainCtrl"
And finally in navService:
angular.module('myApp')
.factory('navService', ['$routeProvider', '$location', function ($routeProvider, $location) {
function getPosition() {
/*code here */
}
return {
getPosition: getPosition
};
}]);
In main app.js
angular
.module('cavyrApp', [
'ngAnimate',
'ngCookies',
'ngMessages',
'ngResource',
'ngRoute',
'ngSanitize',
'ngTouch'
]).config...........
$routeProvider is a provider - you can not inject it into factory/service. You can inject it to the config method only - to configure the service it will provide:
module.config(function($routeProvider) {
// configure the routes here
});
You should inject your factroy like this:
angular.module('myApp',['ngRoute']); //route inject
and the controller:
angular.module('myApp').controller('MainCtrl', function(navService) {
});
I am trying to inject $httpParamSerializer for use in templateUrl but I am having some issues. There isn't any good documentation and examples of how to use $httpParamSerializer.
Example code:
angular.module('myApp', ['ngRoute']).config(
function($routeProvider, $locationProvider, $httpProvider) {
$routeProvider
.when('/data/dashboard', {
templateUrl: function(params) {
//NEED TO USE IT HERE
}
})
})
Things that didn't work, placing it like this:
function($routeProvider, $locationProvider, $httpProvider,$httpParamSerializer ) {
Also in the moduler, like this:
angular.module('myApp', ['ngRoute', '$httpParamSerializer']).config(
Any insight why this isn't working would help.
Since you're in the config you need to get it from the provider itself. That is, inject the provider and call $get
angular.module('myApp', ['ngRoute']).config(
function($routeProvider, $locationProvider, $httpProvider, $httpParamSerializerProvider) {
// get the serializer from the provider
var paramSerializer = $httpParamSerializerProvider.$get();
console.log(paramSerializer({a:1})); // test it
$routeProvider.when('/', {
templateUrl: function(params) {
// you can use paramSerializer(here
}
});
});
Working version of your jsfiddle: http://jsfiddle.net/kh9oeq1y/16/
This forum suggests it's a problem with your angular version. Check that you're using at least 1.4.0.
I have an existing angular/rails app. Everything works fine, except I just added a new module, and the template will not render. Below is my code.
views/printers/orders_index.html.erb
<div ng-app="printers">
<div ui-view></div>
</div>
assets/javascripts/printers/config.js
(function() {
'use strict'
angular.module('printers.controller', [])
angular
.module('printers',
['ngAnimate',
'ui.router',
'templates',
'ngResource',
'printers.controller',
'orders.factories'
])
.config(function ($stateProvider, $urlRouterProvider, $locationProvider) {
/* Routes and States*/
$stateProvider
.state('printers.orders.index', {
url: '/printer_orders_index',
templateUrl: 'orders_index.html',
controller: 'PrintersController'
})
// default fall back route
$urlRouterProvider.otherwise('printers_orders_index')
})
})()
assets/javascripts/printers/controllers/printers_controllers.js
(function() {
'use strict'
angular
.module('printers.controller')
.controller("PrintersController", PrintersController)
PrintersController.$inject = ['$scope', 'Order']
function PrintersController($scope, Order){
Order.query({}, function(response){
$scope.orders = response.orders
$scope.printer_id = response.meta.printer_id
})
}
})()
assets/templates/orders_index.html
(this will not render, it seems it is only rendering the orders_index.html.erb, and the ng-app=printers is not doing anything.)
Meow(h1 tags with Meow in between)
I have tried the sprockets issue, but it has been fixed, i cant think of anything else. Any help would be soooo greatly appreciated!
I'm writing routing logic using ngRoute of angular JS. The following is my code.
index.js
(function() {
'use strict';
function config($routeProvider, $httpProvider, cfpLoadingBarProvider, $tooltipProvider) {
$routeProvider.otherwise({redirectTo: '/404'});
$httpProvider.defaults.withCredentials = false;
$httpProvider.defaults.headers.common['content-type'] = "application/json";
}
angular
.module('pacman', ['ngCookies', 'ngRoute', 'ui.bootstrap', 'ui.validate',
'angular-cache', 'angular-loading-bar', 'angular-md5', 'rt.iso8601', 'ngAnimate']
)
.config(['$routeProvider', '$httpProvider', 'cfpLoadingBarProvider', '$tooltipProvider', config])
.run(['$rootScope', '$location', '$modalStack', '$cookies']);
})();
app.controller.js
(function() {
'use strict';
function config($routeProvider) {
$routeProvider.when('/', {
templateUrl: 'app/components/landingpage/landingpage.html',
controller: 'appController'
});
}
function appController($scope, $rootScope, $location) {
$scope.submitLogin = function() {
alert("Successfully loggedIn");
};
}
angular
.module('pacman')
.controller('appController', ['$scope', '$rootScope', '$location', appController])
.config(['$routeProvider', config]);
})();
notFound.controller.js
(function() {
'use strict';
function config($routeProvider) {
$routeProvider.when('/404', {
templateUrl: 'app/components/notFound/404page.html',
controller: 'notFoundController'
});
}
function notFoundController($scope, $rootScope, $location) {
debugger;
}
angular
.module('pacman')
.controller('notFoundController', ['$scope', '$rootScope', '$location', notFoundController])
.config(['$routeProvider', config]);
})();
My code is a simple app. I'm trying to load different controllers based on routes. However at the time of loading the app, in the last controller's '$routeProvider' it throws an error
Uncaught Error: [ng:areq] Argument 'fn' is not a function, got string
http://errors.angularjs.org/1.4.8/ng/areq?p0=fn&p1=not%20a%20function%2C%20got%20string
I have no clue how to figure out the problem. Any leads would be appreciated.
The following is my library bundle order.
'node_modules/jquery/dist/jquery.js',
'node_modules/angular/angular.js',
'node_modules/angular-route/angular-route.js',
'node_modules/jquery.transit/jquery.transit.js',
'node_modules/angular-cache/dist/angular-cache.js',
'node_modules/angular-cookies/angular-cookies.js',
'node_modules/angular-loading-bar/build/loading-bar.js',
'node_modules/angular-ui-validate/dist/validate.js',
'node_modules/chart.js/Chart.js',
'node_modules/angular-md5/angular-md5.js',
'node_modules/angular-iso8601/dist/angular-iso8601.js',
'node_modules/angular-animate/angular-animate.js',
'node_modules/angular-chart.js/dist/angular-chart.js',
'node_modules/rx/dist/rx.all.js',
'node_modules/angular-ui-bootstrap/ui-bootstrap-tpls.js',
'node_modules/bootstrap/dist/js/bootstrap.js'
Kindly help.
Issue is in your index.js where you define the run method on your angular app.
angular
.module('pacman', []) // removed dependencies for brevity
.run(['$rootScope', '$location', '$modalStack', '$cookies']);
The last argument in the array passed to run should be a function but you forgot to pass a function. Change your run to add some implementation like below or remove the run if you don't see any use for it.
angular.module('pacman', []) // removed dependencies for brevity
.run(['$rootScope', '$location', '$modalStack', '$cookies',
function($rootScope,$location,$modalStack,$cookies){
// some statements here
}]);
Angular JS file declaration must come before the jquery in your index.html
'node_modules/angular/angular.js',
'node_modules/jquery/dist/jquery.js',
I am aware of setting up a controller, service, model etc for prepping for minification. I have about 20 controllers, models and services as individual files and I want to minify and concat them all into one JS file for production.
To get an idea of how I have these files setup, here is an example:
VforumJS.controller('MainController', ['$scope', '$location', '$sce', 'MainModel', 'LogModel', 'MainDebug', 'timecode', 'Idle', function($scope, $location, $sce, MainModel, LogModel, MainDebug, timecode, Idle)
{
...
}]);
After minification, I get the error
Failed to instantiate module VforumJS due to:
Error: [$injector:unpr] http://errors.angularjs.org/1.4.1/$injector/unpr?p0=a
If I click the error link, it says Unknown provider: a
Here is where my module gets created
var VforumJsConfig = function($routeProvider, $locationProvider, localStorageServiceProvider)
{
localStorageServiceProvider.setPrefix('vforumdesktop');
$locationProvider.html5Mode(true);
$routeProvider
.when('/', {
...
})
.otherwise({
...
});
};
var VforumJS = angular.module('VforumJS', ['ngRoute','LocalStorageModule', 'ngTouch', 'ui-rangeSlider','base64','ngIdle'])
.config(['$routeProvider', '$locationProvider', 'localStorageServiceProvider', VforumJsConfig])
.constant('LogTypes', {
LOGIN: 1,
IDLE_LOGOUT: 2,
MANUAL_LOGOUT: 3,
VFORUM_OPEN: 4,
VFORUM_CLOSE: 5
})
.constant('SendLogs', false)
.constant('MainDebug', true);
Am I maybe not doing the proper minification prep in the above code where the module is created?
Here is my Gruntfile.js
'use strict';
module.exports = function(grunt)
{
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
uglify: {
all_src: {
options: {
sourceMap: true,
sourceMapName: 'source.map'
},
src: 'resources/js/**/*.js',
dest: 'composite.all.min.js'
}
}
});
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.registerTask('default', ['uglify']);
};
Your .config is definitely one of the issues. Double check and make sure that everywhere in your code that you are injecting a service/provider that you are using the in-line minification.
This is what a config injecting one provider (just $logProvider for this example) will look like after minification:
.config(function(a){
console.log("Never gets here, but a is", a);
})
When really it should look like this:
.config(['$logProvider', function(a){
console.log("a is", a);
}])
Here is a codepen: http://codepen.io/troylelandshields/pen/xGjKGV
Your VforumJsConfig line is the issue
var VforumJsConfig = function($routeProvider, $locationProvider, localStorageServiceProvider)
The function parameters get minified, and angular doesn't know where to inject them from. You need to supply them as strings ( just like your other functions ), as strings won't be altered during minification.
From the docs:
https://docs.angularjs.org/tutorial/step_05#a-note-on-minification
So you will need to add after the definition of VforumJsConfig:
VforumJsConfig.$inject = ['$routeProvider', '$locationProvider', 'localStorageServiceProvider']
Use the array syntax for VforumJsConfig so that the dependencies are defined explicitly rather than implied by the parameter names which will be minified. Instead of:
var VforumJsConfig = function($routeProvider, $locationProvider,
localStorageServiceProvider)
{
localStorageServiceProvider.setPrefix('vforumdesktop');
$locationProvider.html5Mode(true);
$routeProvider
.when('/', {
...
})
.otherwise({
...
});
};
Try:
var VforumJsConfig = ['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider, localStorageServiceProvider)
{
localStorageServiceProvider.setPrefix('vforumdesktop');
$locationProvider.html5Mode(true);
$routeProvider
.when('/', {
...
})
.otherwise({
...
});
}];