Where is my dependency injection going wrong in my angular application - javascript

To begin with
angular.module('app', [
'ngCookies',
'ngResource',
'ngSanitize',
'ngRoute'
])
Here is my casual factory. Nothing really to see
angular.module('app')
.factory('myFactory', function () {
// Service logic
// ...
// Public API here
return {
isSaved: true
};
});
Here is a controller I use the service in. There is one more like this. They both follow the same pattern
angular.module('app')
.controller('AdvertisersCtrl', [ '$scope', '$location', 'myFactory', function ($scope, $location, myFactory) {
$scope.$emit('controllerChange', 2);
$scope.isFormSave = function () {
// Form Validation
myFactory.isSaved = true;
$location.path('/saved');
};
}]);
And last, but certainly not least. The error I am getting.
Error: [$injector:unpr] Unknown provider: myFactoryProvider <- myFactory
http://docs.angularjs.org/error/$injector/unpr?p0=myFactoryProvider
Also, this project was scaffolded with yoeman, and it uses ngmin.. and all the other packaged grunt tasks yoeman provides.
Thanks folks.

Do you create the module app ?
In the code snippets above both invocations of module() are supposed to retrieve instance of already existing module.
But you have to create it first.
angular.module('app', []) vs. angular.module('app')
more info: http://docs.angularjs.org/guide/module#creation-versus-retrieval

Related

Unknown provider with 2 Services

I am getting the famous Unknown provider error with my node app and can't figure out why.
app.js
var app = angular.module('citigraph', ['addCtrl', 'mygservice', 'stationservice']);
addCtrl.js
var addCtrl = angular.module('addCtrl', ['mygservice', 'rzModule', 'chart.js', 'stationservice']);
addCtrl.controller('addCtrl', function($scope, $http, $rootScope, gservice, stationservice){ ... }
stationservice.js
angular.module('stationservice', []).service('mystationservice', function($http){ ... }
The error in detail:
Error: [$injector:unpr] Unknown provider: stationserviceProvider <-
stationservice <- addCtrl
It looks like you are not using modules correctly. Use a single module name and reuse that module. You can retrieve it again by name if you omit the 2nd set of parameters.
You could create multiple modules but that is generally done when you want to group multiple items together as a piece of functionality.
app.js
// add common external dependencies to this module to the [] array
var app = angular.module('citigraph', []);
addCtrl.js
// add controller to same module
var app = angular.module('citigraph');
app.controller('addCtrl', ['$scope', '$http', '$rootScope', 'gservice', 'stationservice', function($scope, $http, $rootScope, gservice, stationservice){ ... }]
stationservice.js
// add service to same module
angular.module('citigraph').service('mystationservice', ['$http', function($http){ ... }]
Modify your code as below. I think there is some mix up here. Why do you need create two modules for application if they can be combined together.
app.js
var app = angular.module('citigraph', []);
addCtrl.js
var app = angular.module('addCtrl');
app.controller('addCtrl', function($scope, $http, $rootScope, gservice, stationservice){ ... }
stationservice.js
angular.module('citigraph').service('mystationservice', function($http){ ... }
Please refer Angular JS official documentation https://docs.angularjs.org/guide/di for more information.

Where can I define an injectable object so that it's available in all controllers and directives?

Similar to this question: How to create separate AngularJS controller files?
I have a module that has controllers in several files, including controllers that are linked to directives. Where can I declare a factory such that it can be injected into all of them easily?
For example, in app.js I define the app level module
var app = angular.module('myApp', ['ngRoute']);
I would then expect to be able to define a factory in app.js like
app.factory('myFactory', function() { return { myThing: myThing}; });
And then be able to inject it into a controller that looked like
angular.module('myApp')
.controller('Ctrl1', ['$scope', '$http', 'myFactory',
function ($scope, $http, myFactory) {}]);
But I get the error Error: [$injector:unpr] Unknown provider:
Is there a way to do this?

AngularJS $inject error in service injection

I'm newbie in Angular, so will be glad if you can help me.
I split my logic on 2 files (controllers and services).
My services code:
(function () {
'use strict';
angular
.module('app', [])
.factory('authservice', authservice);
authservice.$inject = ['$http', '$logger'];
function authservice($http, $logger) {
return {
signInOwner: signInOwner,
signUpOwner: signUpOwner
};
function signInOwner(owner) {
}
function signUpOwner(owner) {
}
};
})();
My controller code:
(function () {
'use strict';
angular
.module('app', [])
.controller('SignUpController', SignUpController);
SignUpController.$inject = ['authservice'];
function SignUpController (authservice) {
var vm = this;
}
})();
I include my services.js before controller.js but still got error about wrong authservice dependencies
angular.js:14362 Error: [$injector:unpr]
Could you help me, please?
Using this synthax angular.module('app', []), you are overwriting the module creation.
You should use angular.module('app') to retrieve it instead.
[] should be use only once: at the creation of the module.
From the Angular module doc:
Beware that using angular.module('myModule', []) will create the
module myModule and overwrite any existing module named myModule. Use
angular.module('myModule') to retrieve an existing module.
In your controller code replace:
angular
.module('app', [])
.controller('SignUpController', SignUpController);
for
angular
.module('app') // notice the lack of [] here!!
.controller('SignUpController', SignUpController);
This is because with the [] it means you're creating the module and without it it means you're locating the module. Since the module was created when your where creating your service, you don't need to create it again, just locate it.

How to add underscore module to MeanJS?

Ok, first I install this from bower:
bower install angular-underscore-module
Then in modules/core/clients/app/config.js, in line 7 I added the injection:
var applicationModuleVendorDependencies = ['ngResource', 'ngAnimate', 'ngMessages', 'ui.router', 'ui.bootstrap', 'ui.utils', 'angularFileUpload', 'underscore'];
To inject it in my controller, in modules/articles/client/controllers/articles.client.controller.js
I've added it like this:
angular.module('articles').controller('ArticlesController', ['$scope', '$stateParams', '$location', 'Authentication', 'Articles', '_',
function ($scope, $stateParams, $location, Authentication, Articles, _) {
Then, I've got this error:
angular.js:13920 Error: [$injector:undef] Provider '_' must return a value from $get factory method.
Then in this article:
Provider 'xx' must return a value from $get factory method in AngularJs
It says, I should insert { in front of return and Not at the next line, however, I couldn't find that return. Am I doing something wrong here? Please suggest. Thanks.
underscore attaches itself to window object. you don't need to include the dependency in controller. however if you still want to use '_' you could do something like this:
app = angular.module('MyApp', ['underscore']);
app.factory('_', ['$window', function($window) {
return $window._;
});
then you can include '_' as a dependency in your controllers.
Found it!
In your config/assets/default.js, the client.lib.js, you have to include both underscore.min.js and angular-underscore-module.js as code below:
[...]
'public/lib/underscore/underscore-min.js',
'public/lib/angular-underscore-module/angular-underscore-module.js',
[...]

List dependencies injected

Is there a way to know what dependencies were injected into my Angular module?
angular.module('myModule', [
'ui.bootstrap'
])
.controller('myController', [function () {
// var dependencies = Magic.dependencies;
// console.log(dependencies);
}]);
In your controller, if you inject $window, you can dig for the dependencies, specifically, there exists a .requires on your module. To do this, you can either declare your module as a global var so we can find it on our $window, in this case, let's call it app - or - you can bypass globals and $window and call angular.module('myModule').requires directly.
I've added ngRoute as well to prove the array of dependencies that will be discoverable.
var app = angular.module('myModule',
[
'ui.bootstrap',
'ngRoute'
]).controller('ctrl', ['$scope', '$window', function($scope, $window) {
console.log($window.app.requires) // ["ui.bootstrap", "ngRoute"]
console.log(angular.module('myModule').requires) // without global - $window not needed
}]);
JSFiddle Link - working example
Note - If leveraging globals, you can simply call the window as such: window.app.requires - without injecting $window. However, see the AngularJS $window docs to understand why $window is preferred.
Building on #salniro's answer, you don't need globals, or $window.
The dependencies are listed on the .requires property of angular.Module:
angular.module('myModule', [
'ui.bootstrap',
'ngRoute'
])
.controller('ctrl', function() {
var app = angular.module('myModule');
console.log(app.requires); // ["ui.bootstrap", "ngRoute"]
});
http://jsfiddle.net/8vtf6gar/1/

Categories

Resources