Related
I'm building an app with MEAN.JS and I'm trying to use a controller from another module. I've found that I can do this with dependency injection:
angular.module(‘MyModule’, [‘Dependency’]);
But the way modules are created in MEAN.JS is:
ApplicationConfiguration.registerModule('MyModule');
And I can't just pass a second parameter to registerModule. So, how should I do this? Do I have to use both methods? Am I doing it wrong?
Example
I want to add a new model: Campaign. Campaigns are created by admins only, but can be seen by the "campaign owner" (another User). The create campaign form should list available Users, so the admin can select the one that's going to be the "owner" of that Campaign.
The problem is, the create campaign form is controlled by CampaignsController, how can I list Users? I've used another controller (UsersController) and thats the problem, it is undefined because we are in the Campaign module.
EDIT:
The problem was grunt autorestarting the app incorrectly:
I moved the controller from one module (folder) to another, but grunt was still trying to load it from the old path, and thus failing: Controller not found. I thought the problem was dependency injection, but you only have to close grunt (Ctrl+C) and run it again. Problem solved.
Anyways, thanks for the answer #gilBirman cause it is correct: there is no need to inject anything with MEANJS.
MEAN.js makes all the modules registered via registerModule available to all other modules in your app by adding it as a dependency to the main app called mean. Here's the part of the MEAN.js source code that does this:
var applicationModuleName = 'mean';
....
// Add a new vertical module
var registerModule = function(moduleName) {
// Create angular module
angular.module(moduleName, []);
// Add the module to the AngularJS configuration file
angular.module(applicationModuleName).requires.push(moduleName);
};
So you're on the right track, however it sounds like you are trying to inject a controller. However, in angular, controllers are not injectable. You can inject services, factories, values, and constants.
First create your own module for example:
angular.module('app.controllers', []) - angular module with controllers.
then add controller to that module:
angular.module('app.controllers', [])
.controller('dashboard.admin.account.controller', ['$scope', ($scope) { .... }]);
then create global module which will bind to your markup:
angular.module('app', [
'app.controllers'
'ui.router',
'ngAnimate'
]);
then bootstrap your global module to markup:
domReady(function () {
angular.bootstrap(document, ['app']);
});
Now you can use your controller.
I have a bunch of Angular modules declared in my app. I originally started declaring them using the "chained" syntax like this:
angular.module('mymodule', [])
.controller('myctrl', ['dep1', function(dep1){ ... }])
.service('myservice', ['dep2', function(dep2){ ... }])
... // more here
But I decided that wasn't very easy to read, so I started declaring them using a module variable like this:
var mod = angular.module('mymodule', []);
mod.controller('myctrl', ['dep1', function(dep1){ ... }]);
mod.service('myservice', ['dep2', function(dep2){ ... }]);
...
The second syntax seems a lot more readable to me, but my only complaint is that this syntax leaves the mod variable out in the global scope. If I ever have some other variable named mod, it would be overridden with this next one (and other issues associated with global variables).
So my question is, is this the best way? Or would it be better to do something like this?:
(function(){
var mod = angular.module('mymod', []);
mod.controller('myctrl', ['dep1', function(dep1){ ... }]);
mod.service('myservice', ['dep2', function(dep2){ ... }]);
...
})();
Or does it even matter enough to care? Just curious to know what the "best practices" are for module declaration.
'Best' way to declare a module
As angular is on the global scope itself and modules are saved to its variable you can access modules via angular.module('mymod'):
// one file
// NOTE: the immediately invoked function expression
// is used to exemplify different files and is not required
(function(){
// declaring the module in one file / anonymous function
// (only pass a second parameter THIS ONE TIME as a redecleration creates bugs
// which are very hard to dedect)
angular.module('mymod', []);
})();
// another file and/or another anonymous function
(function(){
// using the function form of use-strict...
"use strict";
// accessing the module in another.
// this can be done by calling angular.module without the []-brackets
angular.module('mymod')
.controller('myctrl', ['dep1', function(dep1){
//..
}])
// appending another service/controller/filter etc to the same module-call inside the same file
.service('myservice', ['dep2', function(dep2){
//...
}]);
// you can of course use angular.module('mymod') here as well
angular.module('mymod').controller('anothermyctrl', ['dep1', function(dep1){
//..
}])
})();
No other global variables are required.
Of course it depends all on preferences, but I think this is kind of the best practise, as
you don't have to pollute the global scope
you can access your modules everywhere and sort them and their functions into different files at will
you can use the function-form of "use strict";
the loading order of files does not matter as much
Options for sorting your modules and files
This way of declaring and accessing modules makes you very flexible. You can sort modules via function-type (like described in another answer) or via route, e.g.:
/******** sorting by route **********/
angular.module('home')...
angular.module('another-route')...
angular.module('shared')...
How you sort it in the end is a matter of personal taste and the scale and type of the project. I personally like to group all files of a module inside of the same folder (ordered into sub-folders of directives, controllers, services and filters), including all different test-files, as it makes your modules more reusable. Thus in middle-sized projects I end up with a base-module, which includes all basic routes and their controllers, services, directives and more or less complex sub-modules, when I think they could be useful for other projects as well,e.g.:
/******** modularizing feature-sets **********/
/controllers
/directives
/filters
/services
/my-map-sub-module
/my-map-sub-module/controllers
/my-map-sub-module/services
app.js
...
angular.module('app', [
'app.directives',
'app.filters',
'app.controllers',
'app.services',
'myMapSubModule'
]);
angular.module('myMapSubModule',[
'myMapSubModule.controllers',
'myMapSubModule.services',
// only if they are specific to the module
'myMapSubModule.directives',
'myMapSubModule.filters'
]);
For very big projects, I sometimes end up grouping modules by routes, as described above or by some selected main routes or a even a combination of routes and some selected components, but it really depends.
EDIT:
Just because it is related and I ran into that very recently again: Take good care that you create a module only once (by adding a second parameter to the angular.module-function). This will mess up your application and can be very hard to detect.
2015 EDIT on sorting modules:
One and a half year of angular-experience later, I can add that the benefits from using differently named modules within your app are somewhat limited as AMD still does not really work well with Angular and services, directives and filters are globally available inside the angular context anyway (as exemplified here). There is still a semantic and structural benefit though and it might be helpful being able to include/ exclude a module with a single line of code commented in or out.
It also almost never makes much sense to separate sub-modules by type (eg. 'myMapSubModule.controllers') as they usually depend on each other.
I love the angular-styleguide by Johnpapa, and here are some rules that related to this question:
Rule: Named vs Anonymous Functions
Avoid using anonymous functions:
// dashboard.js
angular
.module('app')
.controller('Dashboard', function() { })
Instead, use named functions:
// dashboard.js
angular
.module('app')
.controller('Dashboard', Dashboard);
function Dashboard() { }
As the author says: This produces more readable code, is much easier to debug, and reduces the amount of nested callback code.
Rule : Define 1 component per file.
Avoid multiple components in one file:
angular
.module('app', ['ngRoute'])
.controller('SomeController', SomeController)
.factory('someFactory', someFactory);
function SomeController() { }
function someFactory() { }
Intead, use one file to define the module:
// app.module.js
angular
.module('app', ['ngRoute']);
one file just uses the module to define a component
// someController.js
angular
.module('app')
.controller('SomeController', SomeController);
function SomeController() { }
and another file to define another component
// someFactory.js
angular
.module('app')
.factory('someFactory', someFactory);
function someFactory() { }
Of course, there are many other rules for modules, controllers and services that are quite useful and worth reading.
And thanks to comment of ya_dimon, the above code should be wrapped in IIFE, for example:
(function (window, angular) {
angular.module('app')
.controller('Dashboard', function () { });
})(window, window.angular);
I recently had this conundrum as well. I had started off just like you using the chained syntax, but in the long run it becomes unwieldy with large projects. Normally I'd create a controllers module, a services module and so on in separate files and inject them into my main application module found in another file. For Example:
// My Controllers File
angular.module('my-controllers',[])
.controller('oneCtrl',[...])
.controller('twoCtrl',[...]);
// My Services File
angular.module('my-services',[])
.factory('oneSrc',[...])
.facotry('twoSrc',[...]);
// My Directives File
angular.module('my-directives',[])
.directive('oneDrct',[...])
.directive('twoDrct',[...]);
// My Main Application File
angular.module('my-app',['my-controllers','my-services','my-directives',...]);
But each one of these files was getting way to large as the project grew. So I decided to break them up into separate files based on each controller or service. I found that using angular.module('mod-name'). without the injection array, is what you need for this to work. Declaring a global variable in one file and expecting that to be readily available in another just doesn't work or could have unexpected results.
So in short my application looked something like this:
// Main Controller File
angular.module('my-controllers',[]);
// Controller One File
angular.module('my-controllers').controller('oneCtrl',[...]);
//Controller Two File
angular.module('my-controllers').controller('twoCtrl',[...]);
I did this to the services file as well, no need to change the main application module file you'd still be injecting the same modules into that.
One other practice is to stuff controllers, directives, etc in their own modules and inject those modules into your "main" one:
angular.module('app.controllers', [])
.controller('controller1', ['$scope', function (scope) {
scope.name = "USER!";
}]);
angular.module('app.directives', [])
.directive('myDirective', [function () {
return {
restrict: 'A',
template: '<div>my directive!</div>'
}
}]);
angular.module('app', [
'app.controllers',
'app.directives'
]);
Nothing is left in the global scope.
http://plnkr.co/edit/EtzzPRyxWT1MkhK7KcLo?p=preview
I like to divide my files and my modules.
Something like this:
app.js
var myApp = angular.module('myApp', ['myApp.controllers', 'myApp.directives', 'myApp.services']);
myApp.config(['$routeProvider', function($routeProvider) {
/* routes configs */
$routeProvider.when(/*...*/);
}]);
directives.js
var myDirectives = angular.module('myApp.directives', []);
myDirectives.directive( /* ... */ );
service.js
var myServices = angular.module('myApp.services', []);
myServices.factory( /* ... */ );
Im not a big fan of the "chained style", so I prefer to write down my variable always.
I suggest to follow Angularjs Style Guide.
They handle all concept from naming convention, to modularize your app and so on.
For angular 2, you can check Angular 2 Style Guide
For me, chaining is the most compact way:
angular.module("mod1",["mod1.submod1"])
.value("myValues", {
...
})
.factory("myFactory", function(myValues){
...
})
.controller("MainCtrl", function($scope){
// when using "Ctrl as" syntax
var MC = this;
MC.data = ...;
})
;
That way I can easily move components between modules, never need to declare the same module twice, never need any global variables.
And if the file gets too long, solution is simple - split into two files, each declaring its own module at the top. For more transparency, I try to keep one unique module per file and name it resembling the full path of the file. This way also I never need to write a module without [], which is a common pain point.
I'd like to work with both angularjs and requirejs. Before that, I worked with backbonejs and requirejs. I felt a bit more comfortable with that combination.
I also got the bower-seed from github, but it's too nested for the beginning.
Here's what I don't understand:
Require forces me to bootstrap angular myself.
Therefore I create a module named by my app.
Then I bootstrap that module to the document.
angular.module('app', []);
angular.bootstrap(document, ['app']);
That happens after the document ist ready, which is checked by this function:
angular.element(document).ready(function() { ... bootstraping ... }
So far I get it. But how and at what point do I put the ng-app into the header?
app.js has the function to put all my controllers, routers etc. into the app. By returning all modules I loaded inside the require-module. In my case I only load controllers
///app.js///
define(['angular', 'controller'], function (angular){
return angular.module('app',[
'app.controller',
'app.router'
]);
});
My controller:
define(['index', 'uirouter'], function(controllers){
controllers.controller('homeCtrl', function($scope, $routeParams){
$scope.logId = "testId";
});
});
Each controller puts it's content in a collection inside the index-module
my Index file:
///index///
define(['angular'], function(angular){
return angular.module('app.controllers',[]);
});
The Index file returs the controller-module to every controller-file requiring it. So I have all controllers in one module, by loading different controller-files
Here's my question: is this procedure correct and can I go on loading all angular-modules like this?
Im confused by working with angular-modules and require-modules ... Maybe anyone got a nice instruction in how to set up a angular-require project easily :)
Here's a link to the project:LINK ;)
Maybe anyone could help me a little bit :)
I am experimenting with this example: https://github.com/nikospara/angular-require-lazy
I also mentioned it in this SO question.
It needs work, but it is working; discussion on this topic really interests me.
I have this interest in automate/simplify angular project with a compiler tool, which might work on everything else, but angular inject and namespacing is awkward enough to escape compiler knowledge. What is the best/professional method for doing this?
thanks, just one last thing,
app.controller('ctrl',['$rootScope',function($rootScope){
...
}]);
works when minified, but how do I minify
app.config(['$routeProvider', function($routeProvider){
}]);
and does it work when I minify successive actions?
app.controller(...).directive(...).run(...)
In Angular, you need to annotate functions for the injector to know which dependencies you want to inject in your function. There are basically three ways to inject dependencies in your function which are being described on official angular website. The three ways are:
1.Use the inline array annotation
yourModule.controller('yourController', ['$scope', function($scope) {}]);
2.Use the $inject property annotation
var yourController = function($scope) {};
yourController.$inject = ['$scope'];
yourModule.controller('yourController', yourController);
3.Implictly from the function parameter names
yourModule.controller('yourController', function($scope) {});
Now when you minify your project, your dependencies names will get renamed.
In first case your code will be like
yourModule.controller('yourController', ['$scope', function(e) {}]);
In third case your code will be like
yourModule.controller('yourController', function(e) {});
It will break your app because angular has no way to recognize your dependency name. So it is advised never to use implicit dependency injection in your project. From the above two inline array annotation is the most popular way amongst programmers.
I would recommend using https://github.com/olov/ng-annotate. It will allow you to write your code like follows.
angular.module("MyMod").controller("MyCtrl", function($scope, $timeout) {
});
and then ngAnnotate turns it into the following which is safe for minification.
angular.module("MyMod").controller("MyCtrl", ["$scope", "$timeout", function($scope, $timeout) {
}]);
The minifyer leaves strings untouched, that's why we use the array notation.
Chaining methods wont change the way the minifyer keeps strings intact.
var app=module(myapp);
app.config(['$routeProvider', function($routeProvider){
$routeProvider.dosomestuffs()
}]);
will be minified in something like
var a=module(myapp);
a.config(['$routeProvider', function(b){
b.dosomestuffs()
}]);
but angular will still find its way around thanks to the '$routeProvider' string.
If you always use annotations there should not be problems minifying angular scripts.
app.controller(['$scope', function(mrScope) {
mrScope.yourProperty = 'it does not matter the dependency variable names if you use annotations';
}]);
As long as you use the array notation for the dependencies you are injecting, no minification trouble is expected. The minification tool you are using should handle any of your examples without trouble (on my project we're using uglify to accomplish that).
In fact, for oddly named injections (named with dots and chars that result in invalid function names like ABC.CDE), the array notation is the best way to inject them.
I had the same problem when minifying, and like you, it only failed for the $routeProvider config elements.. The answer for me was to use the $inject method like Himanshu says for my configs, even though the syntax you show for your first example works for my controllers. So I'll post my .config() code here since I don't see it specifically listed in the answers above:
var app = angular.module('myApp');
var RouteProviderConfig = function ($routeProvider) {
$routeProvider
.when(...)
.otherwise(...);
};
RouteProviderConfig.$inject = ['$routeProvider'];
app.config(RouteProviderConfig);
This fixed my error for configs, but my controllers work the way your first example is written:
app.controller('ctrl',['$rootScope',function($rootScope){
...
}]);
The Angular Documentation seems to suggest that both ways should work, so I think it's possible there is a bug with configs, or $routeProvider, or something else entirely...
I'm trying to "customize" the mongolab example to fit my own REST API. Now I'm running into this error and I am not sure what I am doing wrong:
Error: Unknown provider: ProductProvider <- Product
at Error (unknown source)
at http://localhost:3000/js/vendor/angular.min.js:28:395
at Object.c [as get] (http://localhost:3000/js/vendor/angular.min.js:26:180)
at http://localhost:3000/js/vendor/angular.min.js:28:476
at c (http://localhost:3000/js/vendor/angular.min.js:26:180)
at d (http://localhost:3000/js/vendor/angular.min.js:26:314)
This is my controller:
function ProductListCtrl($scope, Product) {
$scope.products = Product.query();
}
and this is the module:
angular.module('productServices', ['ngResource']).
factory('Product', ['$resource', function($resource){
var Product = $resource('/api/products/:id', { }, {
update: { method: 'PUT' }
});
return Product;
}]);
Your code looks good, in fact it works (apart from the calls themselves) when copied & pasted into a sample jsFiddle: http://jsfiddle.net/VGaWD/
Hard to say what is going on without seeing a more complete example but I hope that the above jsFiddle will be helpful. What I'm suspecting is that you are not initializing your app with the 'productServices' module. It would give the same error, we can see this in another jsFiddle: http://jsfiddle.net/a69nX/1/
If you are planning to work with AngularJS and MongoLab I would suggest using an existing adapter for the $resource and MongoLab: https://github.com/pkozlowski-opensource/angularjs-mongolab
It eases much of the pain working with MongoLab, you can see it in action here: http://jsfiddle.net/pkozlowski_opensource/DP4Rh/
Disclaimer! I'm maintaining this adapter (written based on AngularJS examples) so I'm obviously biased here.
I got that error because I was passing an incorrect parameter to the factory definition. I had:
myModule.factory('myService', function($scope, $http)...
It worked when I removed the $scope and changed the factory definition to:
myModule.factory('myService', function( $http)...
In case you need to inject $scope, use:
myModule.factory('myService', function($rootScope, $http)...
I just had a similar problem.
The error said the same the in the question, tried to solve it with the answer of pkozlowski.opensource and Ben G, which both are correct and good answers.
My problem was indeed different with the same error:
in my HTML-Code I had the initialisation like this...
<html ng-app>
A bit further down I tried to do something like this:
<div id="cartView" ng-app="myApp" ng-controller="CartCtrl">
I got rid of the first one... then it worked... obviously you can't initialise ng-app twice or more times. fair enough.
I totaly forgot about the first "ng-app" and got totaly frustrated. Maybe this is gonna help someone oneday...
Make sure your main app.js includes the services on which it depends. For example:
/* App Module */
angular.module('myApp', ['productServices']).
.....
pkozlowski's answer is correct, but just in case this happens to someone else, I had the same error after creating the same module twice by mistake; the second definition was overriding the provider of the first:
I created the module by doing
angular.module('MyService'...
).factory(...);
then a bit further down in the same file:
angular.module('MyService'...
).value('version','0.1');
The correct way of doing this is:
angular.module('MyService'...
).factory(...).value('version','0.1');
In my case, I've defined a new provider, say, xyz
angular.module('test')
.provider('xyz', function () {
....
});
When you were to config the above provider, you've to inject it with Provider string appended --> xyz becomes xyzProvider.
Ex:
angular.module('App', ['test'])
.config(function (xyzProvider) {
// do something with xyzProvider....
});
If you inject the above provider without the 'Provider' string, you'll get the similar error in OP.
At the end of the JS file to close the factory function I had
});
instead of
}());
This took me way too long to track down. Make sure you minisafe your controller within your directive.
.directive('my_directive', ['injected_item', function (injected_item){
return {
controller: ['DO_IT_HERE_TOO', function(DO_IT_HERE_TOO){
}]
}
}
Hope that helps
To add my own experience in here, I was trying to inject a service into one of my module config functions. This paragraph from the docs which I eventually found explains why that doesn't work:
During application bootstrap, before Angular goes off creating all services, it configures and instantiates all providers. We call this the configuration phase of the application life-cycle. During this phase, services aren't accessible because they haven't been created yet.
Meaning you can inject providers into module.config(...) functions, but you can't inject services, for that you need to wait until module.run(...), or expose a provider you can inject to module.config
For me, this error was caused by running the minified version of my angular app. Angular docs suggest a way to work around this. Here is the relevant quote describing the issue, and you can find the suggested solution in the docs themselves here:
A Note on Minification
Since Angular infers the controller's dependencies from the names of arguments to the controller's constructor function, if you were to minify the JavaScript code for PhoneListCtrl controller, all of its function arguments would be minified as well, and the dependency injector would not be able to identify services correctly.
Since this is the top result for "angularjs unknown provider" on Google right now, here's another gotcha. When doing unit testing with Jasmine, make sure you have this statement in your beforeEach() function:
module('moduleName');
Otherwise you'll get this same error in your tests.
Yet another case where this error will occur, if you're service is defined in a separate javascript file, make sure you reference it! Yes, I know, rookie mistake.
I was forgetting to inject the file that held my services altogether. Remember to do this when initializing your app module:
angular.module('myApp', ['myApp.services', ... ]);
In my case, I used an anonymous function as a wrapper for the angular module, like this:
(function () {
var app = angular.module('myModule', []);
...
})();
After closing the parenthesis, I forgot to call the anonymous function by opening and closing the parentheses again as above.
For me the problem was lazy loading; I loaded my controller and service late, so they were not available at page load (and Angular initialization). I did this with an ui-if tag, but that's irrelevant.
The solution was to load the service with the page load already.
Here's another possible scenario where you can see this error:
If you use Sublime Text 2 and the angular plugin, it will generate stubs like this
angular.module('utils', [])
.factory('utilFactory', [''
function() {
return {
}
}
]);
notice the empty ' ' as the first element of the array after the 'utilFactory' string. If you don't have any dependencies, remove that so it's like this:
angular.module('utils', [])
.factory('utilFactory', [
function() {
return {
}
}
]);
Since this question is top google result, I will add another possible thing to the list.
If the module that you're using has a failure on the dependency injection wrapper, it will provide this same result. For example copy & paste modules from the internet may rely on underscore.js and attempt to inject with '_' in the di wrapper. If underscore doesn't exist in your project dependency providers, when your controller attempts to reference your module's factory, it will get 'unknown provider' for your factory in the browser's console log.
The problem for me was that there were some new javascript files I created that referenced the service yet Chrome saw only the older version. A CTRL + F5 fixed it for me.
I got an "unknown provider" error related to angular-mocks (ngMockE2E) when compiling my project with Grunt. The problem was that angular-mocks cannot be minified so I had to remove it from the list of minified files.
After handling with this error too, I can support this list of answers with my own case.
It's at the same time simple and dumb (maybe not dumb for beginners like me, but yes for experts), the script reference to angular.min.js must be the first one in your list of scripts in the html page.
This works:
<script src="Scripts/angular.min.js"></script>
<script src="MyScripts/MyCartController.js"></script>
<script src="MyScripts/MyShoppingModule.js"></script>
This not:
<script src="MyScripts/MyCartController.js"></script>
<script src="MyScripts/MyShoppingModule.js"></script>
<script src="Scripts/angular.min.js"></script>
Notice about the angular.min.js.
Hope it helps anyone !! :)
My problem was with Yeoman, using (capitalized):
yo angular:factory Test
Made files (uncapitalized):
app/scripts/services/test.js
but the index.html file included (capitalized):
<script src="scripts/services/Test.js"></script>
Hope this helps someone.
Yet another possibility.
I had unknown Provider <- <- nameOfMyService. The error was caused by the following syntax:
module.factory(['', function() { ... }]);
Angular was looking for the '' dependency.
My scenario may be a little obscure but it can cause the same error and someone may experience it, so:
When using the $controller service to instantiate a new controller (which was expecting '$scope' as it's first injected argument) I was passing the new controller's local scope into the $controller() function's second parameter. This lead to Angular trying to invoke a $scope service which doesn't exist (though, for a while, I actually thought that I'd some how deleted the '$scope' service from Angular's cache). The solution is to wrap the local scope in a locals object:
// Bad:
$controller('myController', newScope);
// Good:
$controller('myController, {$scope: newScope});
None of the answers above worked for me, maybe I was doing completely wrong, but as a beginner that's what we do.
I was initializing the controller in a div in order to have a list:
<div ng-controller="CategoryController" ng-init="initialize()">
And then using $routeProvider to map a URL to the same controller. As soon as I removed the ng-init the controller worked with the route.
I had same problem. I fixed that using $('body').attr("ng-app", 'MyApp') instead of <body ng-app="MyApp"> to boostrap.
Because I did
angular.element(document).ready(function () {
angular.bootstrap(document, [App.Config.Settings.AppName]);
})
for architecture requirements.
In my Ruby on Rails app, I had done the following:
rake assets:precompile
This was done in the 'development' environment, which had minified Angular.js and included it in the /public/assets/application.js file.
Removing the /public/assets/* files solved the problem for me.
I faced similar issue today and issues was really very small
app.directive('removeFriend', function($scope) {
return {
restrict: 'E',
templateUrl: 'removeFriend.html',
controller: function($scope) {
$scope.removing = false;
$scope.startRemove = function() {
$scope.removing = true;
}
$scope.cancelRemove = function() {
$scope.removing = false;
}
$scope.removeFriend = function(friend) {
var idx = $scope.user.friends.indexOf(friend)
if (idx > -1) {
$scope.user.friends.splice(idx, 1);
}
}
}
}
});
If you observe the above block, in the first line you will observe I injected $scope by mistake which is incorrect. I removed that unwanted dependency to solve the issue.
app.directive('removeFriend', function() {
return {
restrict: 'E',
templateUrl: 'removeFriend.html',
controller: function($scope) {
$scope.removing = false;
$scope.startRemove = function() {
$scope.removing = true;
}
$scope.cancelRemove = function() {
$scope.removing = false;
}
$scope.removeFriend = function(friend) {
var idx = $scope.user.friends.indexOf(friend)
if (idx > -1) {
$scope.user.friends.splice(idx, 1);
}
}
}
}
});
I had this error after I created a new factory and used it within a component but I did not check the specs of that components
so if the failure in your (specs) test files
you need to add beforeEach(module('YouNewServiceModule'));
Another 'gotcha': I was getting this error injecting $timeout, and it took a few minutes to realize I had whitespace in the array values. This will not work:
angular.module('myapp',[].
controller('myCtrl', ['$scope', '$timeout ',
function ($scope, $timeout){
//controller logic
}
]);
Posting just in case some else has a silly error like this.
My case was dodgy typing
myApp.factory('Notify',funtion(){
function has a 'c' !