Angular having controllers and services in different files - angularjs

I have two controllers and one service in my angular app splitted in 3 different files as follows:
Main controller
var app = angular.module("app",[]);
app.controller("mainController", function(){
console.log("Hi main controller");
})
Second controller
var app = angular.module("app");
app.controller("secondController", ['myCoolService', function($rootScope, myCoolService){
console.log("Hi second controller")
}]);
Service
var app = angular.module("app");
app.service('myCoolService', function() {
});
I've made sure I was importing it correctly:
<script type="text/javascript" src="js/controllers/mainController.js"></script>
<script type="text/javascript" src="js/services/myCoolService.js"></script>
<script type="text/javascript" src="js/controllers/secondController.js"></script>
However I'm getting an unknown service exception:
Unknown provider: $resourceProvider <- $resource <- myCoolService
Can someone help me?

Should be:
var app = angular.module("app");
app.controller("secondController", ['$rootScope', 'myCoolService',
function($rootScope, myCoolService){
console.log("Hi second controller")
}
]);
See, AngularJS injector either gets names of specific dependencies from an array - or uses factory function arguments for them. The first way is actually recommended, as it withstands minification and lets Angular skip parsing the function's argument list.
The point is, AngularJS won't mix those approaches: if list of deps is specified, it IS used, and any hints given by arguments are just ignored. That's why your original code actually puts myCoolService into $rootScope variable (the first dependency is assigned to the first argument), but just doesn't know where to find the second one.

In your second controller you are missing dependency.
var app = angular.module("app");
app.controller("secondController", ['$rootScope', 'myCoolService', function($rootScope, myCoolService){
console.log("Hi second controller")
}]);

Related

Unable to access an angularjs module inside another module

I have an angularJS app with three modules: myApp(parent/core module), services(contains all the factories and services), and controllers(contains all the controllers).
This is my app.js file
angular.module('services', []);
angular.module('controllers', []);
var app = angular.module('myApp', ['services', 'controllers']);
I read here that setting up my modules and defining dependencies in this way will allow each of my modules to access the other without having to inject the dependencies.
Here's my index.html file
<script src="/js/app.js"></script>
<script src="/js/services/testFactory.js"></script>
<script src="/js/controllers/testCtrl.js"></script>
testFactory.js file
angular.module('services').factory('testFactory', ['$rootScope', 'apiCall', function($rootScope, apiCall){
let testFactory = {};
testFactory.testFunc = function(){
console.log('testFactory.testFunc called');
}
return testFactory;
}])
testCtrl.js file
angular.module('controllers').controller('testCtrl', ['$scope', 'testFactory', function($scope, testFactory){
console.log("inside testCtrl");
$scope.testing = function(){
console.log("testing function called");
testFactory.testFunc();
}
}])
When I call the testFactory.testFunc inside the myApp module, it functions correctly. But, when I try calling it in the controller module, I'm getting the following error
TypeError: Cannot read property 'testFunc' of undefined
I even tried injecting the service module inside the controller module as a dependency, but I still got the same error.
How do I get the service module to work inside the controller module?

Unknown provider error when injecting AngularJS factory into controller

I'm trying to inject my factory into my controller and I'm getting this error from AngularJS:
Error: $injector:unpr Unknown Provider
I have looked through almost all of the questions on here and still cannot find a solution to my problem. I believe my controller and factory and declared correctly and the injection is correct but it looks like this isn't the case.
My factory code is as follows:
var app = angular.module('test', []);
app.factory('processingFactory', function () {
var factory = {};
factory.newTest = function() {
console.log("TEST");
}
return factory;
});
This is then injected into the controller which looks like this:
angular.module("test", ["angularModalService", "anguFixedHeaderTable",
'angular-loading-bar', "ngResource", "agGrid",
'ui.tree']).controller("dashboardController", [
"$scope",
"$timeout",
"$http",
"$window",
"$interval",
"$resource",
"ModalService",
"$filter",
'$q',
'processingFactory',
function($scope, $timeout, $http, $window, $interval, $resource,
ModalService, $filter, $q, processingFactory) {
//other code removed
$scope.newWorkorder = processingFactory.newWorkorder;
}
]);
This function is called through a button click on the web page. All of the files needed are in script tags on this html page. I am fairly new to angular so this could be a simple error or something I am not aware of.
Calling angular.module with an array as the second argument declares a module, which can only happen for any given module name. You are declaring the module twice (once in your controller code, and again in your factory code).
Try changing the first part of your factory code to:
var app = angular.module('test');
If you are doing the same thing elsewhere in the app you will need to remove the second argument there too, so that there is only one module declaration in the whole app.
if there are any dependencies for your module "test" why do not you have them declared in the first line itself like:
var app = angular.module("test", ["angularModalService", "anguFixedHeaderTable",
'angular-loading-bar', "ngResource", "agGrid",
'ui.tree']);
Then declare your controller like::
app.controler(...)
Things should work fine.

Cannot add second AngularJS Service Factory

I try to add 2 Services to my AngularJS Module. One should access my Employees and one my Products, but I get an Unknown provider: EmployeeServiceProvider <- EmployeeService <- BookingController.
All Javascript-Files are added to the html.
App/Module
var coffeewatchApp = angular.module('coffeewatchApp', [
'ngRoute',
'coffeewatchControllers',
'coffeewatchServices'
]);
//Routing
var coffeewatchControllers = angular.module('coffeewatchControllers', []);
var coffeewatchServices = angular.module('coffeewatchServices', []);
EmployeeService.js
var coffeewatchServices = angular.module('coffeewatchServices', ['ngResource']);
var employeeServiceUrlPart = "EmployeeService/";
coffeewatchServices.factory('EmployeeService', ['$resource',
function($resource){
return $resource('all/', {}, {
all: {method:'GET',url:REST_BASEURL+employeeServiceUrlPart+"all", params:{}, isArray:true}
});
}]);
ProductController.js is exactly the same but with Product
var coffeewatchServices = angular.module('coffeewatchServices', ['ngResource']);
var productServiceUrlPart = "ProductService/";
coffeewatchServices.factory('ProductService', ['$resource',
function($resource){
return $resource('all/', {}, {
all: {method:'GET',url:REST_BASEURL+productServiceUrlPart+"all", params:{}, isArray:true}
});
}]);
Controller accessing the two Services
coffeewatchControllers.controller('BookingController', ['$scope', 'EmployeeService', 'ProductService',
function ($scope, EmployeeService, ProductService) {
$scope.employees = EmployeeService.all();
$scope.products = ProductService.all();
}]);
Any help is appreciated; Thanks in advance.
EDIT:
I implemented the EmployeeService first and everything was working great.
So I don't really understand why adding the ProductService kills my EmployeeService. The only thing I can think of is that the ProductService somehow "overwrites" my EmployeeService because it gets injected second.
All added JS-Files in index.html
<script src="js/config/app-config.js"></script>
<script src="js/app.js"></script>
<script src="js/controllers/DashboardController.js"></script>
<script src="js/controllers/StatisticController.js"></script>
<script src="js/controllers/BookingController.js"></script>
<script src="js/services/EmployeeService.js"></script>
<script src="js/services/ProductService.js"></script>
EDITEDIT
After looking at this answer I am even more confused why my code is not working, but maybe the other code will help somone spotting the difference.
In both of your controller files, retrieve the module like this (remove dependency list) -
var coffeewatchServices = angular.module('coffeewatchServices');
Add the dependency to ngResource here instead, while declaring in App/Module -
var coffeewatchServices = angular.module('coffeewatchServices', ['ngResource']);
Your module is getting re-created on the second call in ProductController, so overriding previous module and service definitions.

Why should retrieved module name should be same as the module name passed in the first argument in angular.module

I have written a program which uses angular modules.
I have created a module as follows:
// Module A
var modA = angular.module("moduleA",[]);
//Controller A
modA.controller("AController", function($scope, $rootScope, $log){
$log.info("In controller A");
$scope.message = "I am in controller A";
});
Created some another module and controller.
Created a new angular module using above created modules as :
var myApp = angular.module("mainModule",["modA","moduleB"]);
But when I run the code, I am getting the following error:
Uncaught Error: No module: modA
But when I change the retrived module name "modA" to "moduleA" which is passed as first argument in module in while creating it works. May I know the reason/explanation why it is so?
The full code is as follows:
<!DOCTYPE HTML>
<html ng-app="mainModule">
<head>
<script type="text/javascript" src="../js/angular.js"></script>
<script text="text/javascript">
// Module A
var modA = angular.module("moduleA",[]);
//Controller A
modA.controller("AController", function($scope, $rootScope, $log){
$log.info("In controller A");
$scope.message = "I am in controller A";
});
// Module B
var moduleB = angular.module("moduleB",[]);
// Controller B
moduleB.controller("BController", function($scope, $rootScope, $log){
$log.info("In controller B");
$scope.message = "I am in controller B";
});
var myApp = angular.module("mainModule",["modA","moduleB"]);
</script>
</head>
<body>
<div ng-controller="AController">
<span>{{message}}</span>
</div>
<div ng-controller="BController">
<span>{{message}}</span>
</div>
</body>
</html>
A module is a collection of configuration and run blocks which get applied to the application during the bootstrap process.
Modules can list other modules as their dependencies. Depending on a module implies that required module needs to be loaded before the requiring module is loaded.
In your case you are injecting "modA"
var myApp = angular.module("mainModule",["modA","moduleB"]);
which is not declared before hence cannot be loaded.
Due to which it throws an error during "Dependency Injection".
This is happening during Asynchronous loading mechanism of VM to execute modules, because modules do nothing at load time they can be loaded into the VM in any order and thus script loaders can take advantage of this property and parallelize the loading process.
You may refer to link for further info.
Angular's error is during Dependency Injection. The injector uses the module/component names you specify:
var modA = angular.module("moduleA",[]);
In that case you are telling it to create a module named "moduleA" with the dependencies of no other module. It doesn't care what you named the variable, it simply registers it by the name you give. In fact, you don't even need to store the return value because you can chain it or retrieve it
angular.module('moduleA').controller('MyOtherCtrl', function()...);
When you call angular.module(name) with no second argument it retrieves the module by name so you can add components to it that way as well.

Including 3rd Party Modules in Angular App

I would like to include a couple of 3rd party Angular modules in my App. Previously I have only created simple apps that I simply use ng-app to bootstrap and put my code inside the controller.
From my understanding I should have something like this in my html:
<html ng-app"myApp">
Then my JS should look something like this:
angular.module('myApp',['thirdPartyModule1','thirdPartyModule2']);
var myCtrl = function($scope, myApp, $http){
//my stuff
};
But when I do this I get an error:
Error: Unknown provider: myAppProvider <- myApp
You don't need to inject myApp into the controller. Your controller should be defined like this:
angular.module('myApp',['thirdPartyModule1','thirdPartyModule2']);
var myCtrl = function($scope, $http){
//my stuff
});
to make it a little more "standard":
var myApp = angular.module('myApp',['thirdPartyModule1','thirdPartyModule2']);
myApp.controller('myCtrl', function($scope, $http){
//my stuff
});
This way you can have a reference to your app if you like.
Now to make it compatible with minifiers/beautifiers/closure compiler:
var myApp = angular.module('myApp',['thirdPartyModule1','thirdPartyModule2']);
myApp.controller('myCtrl', ['$scope','$http', function($scope, $http){
//my stuff
}]);
That basically makes the controller argument an array, where the first members of the array are what you're going to inject. This is because a minifier will turn the arguments into random letters like function(a,b) and angular won't know what the heck you want to inject. By passing strings in the array thy will be minified like so ['$scope','$http', function(a,b)] which is fine because the first two arguments in the array tell angular what to inject.

Resources