Angularjs - injecting dependencies into multiple controllers - angularjs

I'm still quite new to angular, and have been building a simple CRM application. For a single resource (restful API resource) I have 3-4 routes and controllers defined in my angular application. Now, there are a set of services and modules that I repeatedly have to inject into each controller. I understand that each controller will have it's own instance of scope and shared instance of factory/services but is there a way to centrally define dependencies for multiple controllers?
In the example below, $modal, growl, configuration, $scope are injected into all 3 controllers, I'd like to define that only once.
Listings Controller
myApp.controller('VenueListCtrl', ['$scope', '$http', 'configuration', '$modal', 'growl',
function ($scope, $http, configuration, $modal, growl) {
}
]);
Create/New Controller
myApp.controller('VenueCreateCtrl', ['$scope', '$http', '$location', 'configuration',
function ($scope, $http, $location, configuration) {
}
]);
Details Controller
myApp.controller('VenueDetailCtrl', ['$scope', '$routeParams', '$http', '$modal', 'configuration',
function ($scope, $routeParams, $http, $modal, configuration) {
}
]);

Best you can do is: use not-anonymous function declaration of controllers:
var depsToInject = ['$scope', 'growl', 'configuration', '$modal'];
myApp.controller('Ctrl1' , Ctrl1);
Ctrl1.$inject = depsToInject ;
function Ctrl1($scope, growl, configuration, $modal) {
// ...
}
myApp.controller('Ctrl2' , Ctrl2);
Ctrl2.$inject = depsToInject ;
function Ctrl1($scope, growl, configuration, $modal) {
// ...
}
etc. But that does not fully unify declaration and I don't think there is a better way. However you can try from the other side and wrap your dependencies with another dependency, but I don't like this way either.

Related

Grouping Angular services together to inject them in multiple Controllers

I am currently trying to refactor everything on our company following best practices and JohnPapa's style guide, which means that among other things, I am supposed to switch from setTimeout to $timeout, setInterval to $interval, etc.
However, I find it tiring, messy, and counter-intuitive to have to inject those services every single time. This results in long repetitive controller declarations where half of the elements are useless and obvious.
angular.module('myModule',[])
.controller('MyController', ['$scope', '$http', '$timeout', '$interval', MyController])
.controller('MyController2', ['$scope', '$http', '$timeout', '$interval', MyController2])
.controller('MyController3', ['$scope', '$http', '$timeout', '$interval', MyController3])
I find this ugly, and a pain to maintain; this is the reason why I've always favored setTimeout over $timeout, but now I'm trying to improve.
Would there be a way to "mass inject" services?
For example something such as:
var baseServices = {
http: $http,
scope: $scope,
timeout: $timeout,
interval: $interval,
};
angular.module('myModule',[])
.controller('MyController', ['baseServices', MyController])
.controller('MyController2', ['baseServices', MyController2])
.controller('MyController3', ['baseServices', MyController3])
var MyController = function(baseServices){
baseServices.$timeout(...);
}
Is this something remotely possible?
Maybe you could use a factory to group all these services and use it from your controller
angular.module('myModule',[])
.controller('MyController', ['baseServices', MyController])
angularApp.factory('baseServices', baseServices );
function baseServices ($scope, $http, $timeout, $interval) {
return {
scope: $scope,
http: $http,
timeout: $timeout,
interval: $interval
};
}

Working with multiple factories in angular

I was working with only 1 factory in angular, but now that my project has grown too large, I want to split the file in separate factories.
My factories are like this:
angular.module('factories')
.factory('auth', ['$http', '$state', '$window',
function($http, $state, $window) {
var auth = {};
......
return auth;
Userfactory:
angular.module('factories')
.factory('userFactory', ['$http', '$state', '$window',
function($http, $state, $window) {
var userFactory = {};
return userFactory;
I inject them in my controllers:
angular.module('controllers')
.controller('UserCtrl', ['$scope', '$state', 'auth', 'userFactory', 'Facebook',
function ($scope, $state, auth, userFactory, Facebook) {
However I get the following error:
Error: [$injector:unpr]
http://errors.angularjs.org/1.4.7/$injector/unpr?p0=userFactoryProvider%20%3C-%20userFactory%20%3C-%20UserCtrl
I'm also bootstrapping my factories:
angular.module('factories', []);
And I inject factories into app.js:
var app = angular.module('eva', ['ui.router', 'ngMaterial', 'ngMessages',
'controllers', 'factories', 'ngAnimate', '720kb.socialshare',
'angular-loading-bar', 'angular-svg-round-progress', 'pascalprecht.translate',
'facebook']);
What is the proper way to work with multiple factories?
Check if you imported the script into your index file. You need files from both of services to be imported after the angular.js file.
Since factories are in a separate module so you need to set dependency for controller module because it is using factories from factories module.
Do something like
angular.module('controllers', ['factories'])
.controller('UserCtrl', ['$scope', '$state', 'auth', 'userFactory', 'Facebook',
function ($scope, $state, auth, userFactory, Facebook) {

Can I have two angular.module calls to the same ng-app in two different files for same controller?

Hi I have created two angulerjs files for same ng-app example.
admin.js
var app = angular.module('arcadminmodule', ['ngTable', 'ui-notification']);
app.controller('ArcAdminController', ['$http', '$scope', '$filter', '$interval', 'ngTableParams', 'Notification', function($http, $scope, $filter, $interval, ngTableParams, Notification) {});
admin1.js
var app = angular.module('arcadminmodule');
app.controller('ArcAdminController', ['$http', '$scope', '$filter', '$interval', 'ngTableParams', 'Notification', function($http, $scope, $filter, $interval, ngTableParams, Notification) {});
But its overriding admin.js from admin1.js
please help me out....
In admin1.js when you write:
var app = angular.module('arcadminmodule');
you are not creating a new module. You are trying to get an existing module named 'arcadminmodule'.. If you want to create a new module, you will have to write something like this:
var app = angular.module('arcadminmodule',[]); // add your depencencies...
Now, In your case, in admin.js you are creating your module and admin1,js you are making use of the same module. In angular you cannot have two controllers with the same name. Controllers are for (from the docs):
Set up the initial state of the $scope object.
Add behavior to the $scope object.
So If you need are trying to apply some roles or some business logic, It need to go into one controller. Make sure your controller contain only the business logic needed for a single view.
I think its no need for use the same controller in two places.But you can use services in places.If you need to do some think different from the ArcAdminController,use this structure.
Services
-service1.js
(function (angular) {
angular.module('marineControllers').service('boatService', function (ajaxService) {
}
)
-service2.js
-module..js
var artistControllers = angular.module('marineControllers',['ngAnimate']);
Controllers
-controller1
(function (angular) {
angular.module('marineControllers').controller("BoatController", ['$scope', '$http', '$routeParams',
'dashboardService', '$filter', 'loginService', '$location', 'boatService', 'autocompleteFactory', 'utilityFactory',
function ($scope, $http, $routeParams, dashboardService, $filter, loginService, $location, boatService, autocompleteFactory, utilityFactory) {
function loadAllFishingBoat() {
$scope.boatsTable.length = 0;
if (!$scope.$$phase)
$scope.$apply();
boatService.getAllBoatAndDevice().then(function (data) {
$scope.boatsTable = data;
if (!$scope.$$phase)
$scope.$apply();
});
};
}]);
})(angular);
-controller2
(function (angular) {
angular.module('marineControllers').controller("DeviceController", ['$scope', '$http', '$routeParams',
'dashboardService', '$filter', 'loginService', '$location', 'deviceService', 'autocompleteFactory', 'utilityFactory','commonDataService',
function ($scope, $http, $routeParams, dashboardService, $filter, loginService, $location, deviceService, autocompleteFactory, utilityFactory,commonDataService) {
function loadAllFishingBoat() {
$scope.boatsTable.length = 0;
if (!$scope.$$phase)
$scope.$apply();
boatService.getAllBoatAndDevice().then(function (data) {
$scope.boatsTable = data;
if (!$scope.$$phase)
$scope.$apply();
});
};
}]);
})(angular);
I have been use many services in both controllers,still they are different logics.

multiple controllers and files in angularjs

I have multiple controllers in multiple files.
on one page I use two controllers.
Now I get the error '&p1=not%20a%20function%2C%20got%20undefined'
app.js:
var app = angular.module('demo', ['MainControllers', 'MainServices'])
.constant('myConfig', {
'backend': 'http://localhost:7645',
});
controller 1:
angular.module('MainControllers', ['ui.bootstrap'])
.controller('DemoOneController', function($scope, $rootScope, $modal, mainService) {
Controller 2:
angular.module('MainControllers', ['ui.bootstrap'])
.controller('DemoTwoController', function($scope, $rootScope, $modal, mainService) {
controller 3:
angular.module('MainControllers', ['ui.bootstrap'])
.controller('ModalDemoCtrl', function ($scope, $modal, $log) {
what is wrong?
when u use angular.module('MainControllers', ['ui.bootstrap']) will override the previous module you define with MainControllers name. you need only one definition of the module so u can do like this,
angular.module('MainControllers', ['ui.bootstrap'])
.controller('DemoOneController', function($scope, $rootScope, $modal, mainService) {
angular.module('MainControllers')
.controller('DemoTwoController', function($scope, $rootScope, $modal, mainService) {
angular.module('MainControllers')
.controller('ModalDemoCtrl', function ($scope, $modal, $log) {
removing , ['ui.bootstrap'] from second and third controllers will solve the overriding issue,
when angular finds module dependency array with or without empty like
angular.module('MainControllers', []) //without dependency
angular.module('MainControllers', ['ui.bootstrap']) //with dependency
it will override the module.
if you do like angular.module('MainControllers').controller('Mo....` //without dependency array
it will check for the module with the name MainControllers which is already defined and assign the controller to that module.
here is the demo Plunker

how to pass multiple services in controller in angularjs?

I have a service called authService. I call it from the Logincontroller as follows :
angular.module('myApp').controller('LoginController',function($q, $scope, $location,$routeParams, $window, authService) {//some code here});
this works fine.
Now I have another service called regService which is like :
angular.module('myApp').factory('regService ', function ($window, $q, $rootScope) {//some code here});
Now in LoginController how do I call functions from regService ?
Both existing answers are technically correct, but if you decide to minify/uglify your code anytime in the future, those solutions will eventually break.
To prevent this, John Papas AngularJS style guide favors the use of the $inject service in Y091 like so :
angular.module('myApp').controller('LoginController', LoginCtrl);
LoginCtrl.$inject = ['$q', '$scope', '$location', '$routeParams', '$window', 'authService', 'regService'];
function LoginCtrl($q, $scope, $location, $routeParams, $window, authService, regService) {
//some code here
}
Just do it like authService, you just need to add regService. AngularJS will automatically bind the service based on name. You might want to understand more about Dependency Injection - https://docs.angularjs.org/guide/di
angular.module('myApp').controller('LoginController',function($q, $scope, $location,$routeParams, $window, authService, regService) {//some code here});
Just do:
angular.module('myApp')
.controller('LoginController', function($q, $scope, $location, $routeParams, $window, authService, regService) {
});

Resources