Im pretty new and trying to build a app Its working fine
Now I am trying to minify the files:
Error: Unknown provider: aProvider <- a
uglify: {
my_target: {
files: {
'app/output/output.js': [
'app/js/angular-ui-router.js',
'app/js/angular-animate.js',
'app/js/packery.pkgd.js',
'app/js/app.js',
'app/js/services.js',
'app/js/controllers.js',
'app/js/directives.js'
]
}
}
}
1) How to solve this problem?
2) Some of blog examples suggesting to use grunt-contrib-concat before uglify use - why?
Second question is confusing me
Edit:
After read about ng-annotate
They Must be written using the array syntax.
My code strcture like this
var app = angular.module('bigApp', []);
app.controller('mainController', ['$scope', function($scope) {
$scope.message = 'HOORAY!';
}]);
But didnt solve error 'Unknown provider: aProvider <- a'
The files should be concatenated before you uglify them and the reason why is that uglify will change names of functions, controllers and so on, when you do it like in your example the files will be uglified out of context of the whole application and renamed functions cant be found properly. And to uglify Angularjs properly you should have ng-annotate in grunt as well, unless you already use following notation in controllers/services/factories
need ng-annotate
.controller('myController', function (serviceA, factoryB, filterC){
//something fancy
})
dont need ng-annotate
.controller('myController', [ 'serviceA', 'factoryB', 'filterC', function (serviceA, factoryB, filterC){
//something fancy
}])
Related
I am attempting to upgrade a large angular.js app (1.5.9) to the latest version of Angular.
I am in the process of turning the app into a hybrid AngularJs/Angular app and have reached this step in the guide:
https://angular.io/guide/upgrade#bootstrapping-hybrid-applications
So far I have changed from using gulp to webpack 4 and the app is working the same as before.
The issue I am having is, when I switch from using the ng-app directive in my index.html to bootstrapping in Javascript the app fails to start, throwing this error:
Uncaught Error: [$injector:unpr] Unknown provider: StateServiceProvider <- StateService
This is coming from my app.js file which looks like this:
angular.module('app-engine', [
'app-engine.state',
'app-engine.api',
// other modules
])
.factory('bestInterceptor', bestInterceptor)
// other configs which aren't throwing Unknown provider errors
.run(startUp);
bestInterceptor.$inject = ['StateBootstrappingService'];
function bestInterceptor(StateBootstrappingService) {
return {
request: config => {
if (!StateBootstrappingService.isBestSsoOn()) {
config.headers['x-impersonated-user'] = StateBootstrappingService.getUserName();
}
return config;
}
};
}
startUp.$inject = ['$rootScope', '$state', '$timeout', 'StateService']
function startUp($rootScope, $state, $timeout, StateService) {
// start up code
}
There is a separate app.modules.js file, which defines the other modules in the app.
Including:
angular.module('app-engine.state', ['rx', 'app-engine.api']);
The service which is mentioned in the Unknown provider error looks like this:
(function() {
'use strict';
angular
.module('app-engine.state')
.factory('StateService', StateService);
StateService.$inject = [
'$state',
'$log',
'rx',
// a few other services that exist in the app
];
function StateService(
// all the above in $inject
) {
// service code
}
})();
As the guide instructs, I am removing the ng-app="app-engine" from my index.html and adding it into the JavaScript instead. I've added it at the bottom on my app.modules.js file.
angular.bootstrap(document.body, ['app-engine']);
After this change is when the Unknown provider error is thrown. I have confirmed the source is my startUp function in app.js. I have tried including all the modules in the app in the 'app-engine' requires array, which did not change anything. It's interesting that the bestInterceptor function is not throwing any errors, despite also using a service (The StateBootstrappingService is being set up in the same way as the StateService).
Is there anything obvious I am doing wrong? Or anyone have any ideas how to solve this?
Try this:
angular.element(document).ready(function () {
angular.bootstrap(document.body, ['app-engine'])
})
For me this was necessary because the other sub components (providers and services) had not yet been added to the module yet. Running the it on "document.ready()" gives those items an opportunity to attach before trying to manually bootstrap (because they cannot be added later when manually bootstrapping)
I don't love the use of document.ready() so I'm still looking for a more offical way to do this
Can anybody show an example of what gulp-angular-filesort really does and how to use it properly?
The thing is that I’ve recently realized that my gulp-angular-filesort doesn’t sort angularjs files at all, however my AngularJS App with lots of files works fine.
So, I’ve come up with two questions:
Is AngualarJs still sensitive for source files order? As to me, it looks like it isn’t.
What gulp-angular-filesort actually does? I can’t see any results of its work.
I’ve thought that gulp-angular-filesort looks at angular.module statements and sort files according to specified dependency in the brackets. It looks like I was wrong.
Please look at my sample below.
// File: Gulpfile.js
'use strict';
var
gulp = require('gulp'),
connect = require('gulp-connect'),
angularFilesort = require('gulp-angular-filesort'),
inject = require('gulp-inject');
gulp.task('default', function () {
gulp.src('app/index.html')
.pipe(inject(
gulp.src(['app/js/**/*.js']).pipe(angularFilesort()),
{
addRootSlash: false,
ignorePath: 'app'
}
))
.pipe(gulp.dest('app'))
;
connect.server({
root: 'app',
port: 8081,
livereload: true
});
});
//a_services.js
'use strict';
angular.module('myServices', [])
.factory('MyService', function () {
return {
myVar:1
};
})
;
//b_controllers.js
'use strict';
angular.module('myControllers', ['myServices'])
.controller('MyController', function ($scope, MyService) {
$scope.myVar = MyService.myVar;
})
;
// c_app.js
'use strict';
angular.module('myApp', ['myControllers']);
The result of gulp-inject is the following:
<!-- inject:js -->
<script src="js/c_app.js"></script>
<script src="js/b_controllers.js"></script>
<script src="js/a_services.js"></script>
<!-- endinject -->
I was expected exactly an opposite order to make the App work (however it still does work).
So, using of gulp-angular-filesort simply sorted files alphabetically, despite of all the dependencies specified in the angular.module(...,[...])
What is going on here?
Actually in your case you don't need gulp-angular-filesort because you declare a module for each file. The dependency injection mechanism for angular will figure out the correct way to call your modules according to your dependencies.
You'll need gulp-angular-filesort only when you have one module spread across multiple files. So for your example if all files use 'myApp' as the module name. Then the plugin will sort the files correctly: always the one with dependencies before the others.
Here your example modified so that gulp-angular-filesort is needed:
//a_services.js
'use strict';
angular.module('myApp')
.factory('MyService', function () {
return {
myVar:1
};
})
;
//b_controllers.js
'use strict';
angular.module('myApp')
.controller('MyController', function ($scope, MyService) {
$scope.myVar = MyService.myVar;
})
;
// c_app.js
'use strict';
angular.module('myApp', []);
In this case this will still be:
c_app.js
b_controller.js
a_service.js
gulp-angular-filesort moves files containing module’s declaration above the files wherein the modules are mentioned.
If the module is mentioned before it declared, you’ll got errors like these:
"angular.js:68 Uncaught Error: [$injector:nomod] Module 'myApp' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument."
"angular.js:13294 Error: [ng:areq] Argument 'MyController' is not a function, got undefined"
I'm trying to test my angular project and keep falling at the first hurdle. By just instantiating my module without even testing anything karma is throwing an error.
If I do include an it statement karma gives me an error saying 'Error: [$injector:modulerr]'. I'm using ngRoute in my project and I'm wondering if that has anything to do with it.
Here's my code, any suggestions on what could be wrong would be much appreciated.
angular.module('MyApp', ['ngRoute'])
.controller('HomeCtrl', ['loadArtists', function(loadArtists){
var self = this;
self.homeArtistsArray = [];
self.homeArtistsArray = loadArtists;
}])
-
describe('Practice', function(){
beforeEach(module('MyApp'));
var ctrl;
beforeEach(inject(function($controller){
ctrl = $controller('HomeCtrl');
}))
it('should do nothing',function(){
})
});
-
files: [
'jquery-1.11.3.min.js',
'angular.js',
'angular-mocks.js',
'js/app.js',
'js/appControllers.js',
'js/appFactory.js',
'js/testFile.js'
],
If ngRoute is the problem could you suggest somewhere to download it from.
You need to add angular-route.js to your karma configuration.
BTW, when debugging, you should use the not-minified angular.js file, so you get a full debug message with the error (here, modulerr).
I am trying to set up unit testing with Angular and have hit a bit of a wall with injecting into the module level config and run methods.
For example, if I have a module definition as such:
angular.module('foo', ['ngRoute', 'angular-loading-bar', 'ui.bootstrap']).config(function ($routeProvider, $locationProvider, datepickerConfig, datepickerPopupConfig) {
Karma yells at me because I am not properly mocking $routeProvider, datepickerConfig, etc with the following:
Error: [$injector:modulerr] Failed to instantiate module foo due to:
Error: [$injector:unpr] Unknown provider: $routeProvider
(and then if I remove $routeProvider then it says Unknown provider: datepickerConfig and so on)
I also have the following code in a beforeEach:
angular.mock.module('foo');
angular.mock.module('ngRoute');
angular.mock.module('ui.bootstrap');
And the following in my karma.conf.js:
'components/angular/angular.js',
'components/angular/angular-mocks.js',
'components/angular/angular-route.js',
'components/angular-ui/ui-bootstrap-tpls.js',
'app/*.js', // app code
'app/**/*.js',
'app/**/**/*.js',
'test/app/*.js', // app.js
'test/specs/*.js', // angular.mock.module calls
'test/**/*.js', // tests
'test/**/**/*.js'
Thank you for any advice.
Make sure to include the angular-route module and all your dependencies into the flies array of your karma.conf.js. That should do the trick.
I also have the following code in a beforeEach:
angular.mock.module('foo');
angular.mock.module('ngRoute');
angular.mock.module('ui.bootstrap');
I don't think you need to mock ngRoute and ui.bootstrap
Generally I just set
describe('myApp', function() {
beforeEach(module('foo'));
it('should do something awesome', function() {
// arrange
// act
// assert
});
});
I'm trying for the first time to use AngularJS in conjunction with RequireJS using this guide as a basis. As far I can tell after a lot of debugging I'm loading all my modules in the correct order, but when the application runs Angular throws an Error / Exception with the following message:
Argument 'fn' is not a function, got string from myApp
I've seen this message before due to syntax errors, so even though I've looked trough the code multiple times I won't rule out the possibility of a simple syntax error. Not making a Fiddle just yet in case it is something as simple as a syntax error, but I'll of course do so if requested.
Update: I just noticed when setting ng-app="myApp" in the <html> tag I also get an additional error,
No module: myApp
Update II: Okay, it turns out it indeed was an syntax error in the only file not included below. I am though still left with the problem from update I.
RequireJS bootstrap
'use strict';
define([
'require',
'angular',
'app/myApp/app',
'app/myApp/routes'
], function(require, ng) {
require(['domReady'], function(domReady) {
ng.bootstrap(domReady, ['myApp']);
});
});
app.js
'use strict';
define([
'angular',
'./controllers/index'
], function(ng) {
return ng.module('myApp', [
'myApp.controllers'
]);
}
);
controllers/index
'use strict';
define([
'./front-page-ctrl'
], function() {
});
controllers/module
'use strict';
define(['angular'], function (ng) {
return ng.module('myApp.controllers', []);
});
controllers/front-page-ctrl
'use strict';
define(['./module'], function(controllers) {
controllers.
controller('FrontPageCtrl', ['$scope',
function($scope) {
console.log('I\'m alive!');
}
]);
});
Delete ng-app="myApp" from your html.
Because it has bootstrapped manually
ng.bootstrap(domReady, ['myApp']);
RequireJS docs on Dom ready state:
Since DOM ready is a common application need, ideally the nested
functions in the API above could be avoided. The domReady module also
implements the Loader Plugin API, so you can use the loader plugin
syntax (notice the ! in the domReady dependency) to force the
require() callback function to wait for the DOM to be ready before
executing. domReady will return the current document when used as a
loader plugin:
So, when you require 'domReady' the result is a function:
function domReady(callback) {
if (isPageLoaded) {
callback(doc);
} else {
readyCalls.push(callback);
}
return domReady;
}
But when you append the domReady string with ! sign the result will be the actual document element:
'use strict';
define([
'require',
'angular',
'app/myApp/app',
'app/myApp/routes'
], function(require, ng) {
require(['domReady!'], function(domReady) {
// domReady is now a document element
ng.bootstrap(domReady, ['myApp']);
});
});