Angularjs: Injecting one controller in another failed - angularjs

I have this controller A which I'm trying to inject in every other controller.
What controller A does is, it communicates with a factory (which does some authentication services, communicates with database)
My factory looks like this and I named it myFactoryServices.js and included the link to it in my index page.
(function() {
angular
.module('myApp.myFactoryServices', [])
.factory('FactoryService', ["$http", "$location", function($http, $location){
var my = this;
my.someFunction = function()
{
//communiate with backend and return data
}
return my;
}]);
})();
and my Controller A looks like this:
(function() {
angular
.module('myApp.ControlA', [])
.controller('ControllerA', function($scope,$routeParams, FactoryService) {
var my = this;
FactoryService.someFunction();
});
})();
And I am trying to inject this controller in every other controller, but it does not work. I am pretty new to this kind of programming, can anyone tell me where I made mistake?
This is how I tried injecting a controller into another.
(function() {
angular
.module('myApp.ControlB', [])
.factory('ControllerBService', function($http) {
var baseUrl = 'backendurl/';
return {
getInfo: function() {
return $http.get(baseUrl+ 'getInfo');
}
};
})
.controller('ControllerB', function($scope,$routeParams, ControllerBService,ControllerA) {
var my = this;
});
})();
No error is coming, and the controller is not getting injected as I am not able to use those factory services. is this the correct method?

First of all you cannot inject controller to another controller, and One simple solution would be, instead of having each angular modules for each components, declare a module and add the factory service to controllers as dependency.
Code:
var app = angular.module('myApp', []);
app.factory('FactoryService', ["$http", "$location", function($http, $location){
var my = this;
my.someFunction = function()
{
//communiate with backend and return data
}
return my;
}]);
app.controller('ControllerA', function($scope,$routeParams, FactoryService)
{
var my = this;
FactoryService.someFunction();
});
app.controller('ControllerB', function($scope,$routeParams, FactoryService)
{
var my = this;
FactoryService.someFunction();
});

Controllers are not injectable, because controller is not singleton. Controllers are constructor functions used to create instances of controllers. For example you can have multiple instances of one controller in your app:
angular.module('app', []);
angular
.module('app')
.controller('Example', function () {
this.x = Math.random();
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.js"></script>
<div ng-app="app">
First instance: <br>
<div ng-controller="Example as Ex1">
{{Ex1.x}}
</div>
Second instance: <br>
<div ng-controller="Example as Ex2">
{{Ex2.x}}
</div>
</div>
So if you want to share some behavior between controller you should use factory instead.

To inject a controller into another controller, use the $controller service.
app.controller('ControllerB', function($scope,$routeParams, $controller) {
var my = this;
$scope.ctrlA = $controller("ControllerA", {$scope: $scope});
});
The above example creates an instance of ControllerA as ctrlA with its $scope injected with the scope of the parent controller.
For more information, see AngularJS $controller Service API Reference.

Related

How can i get a variable from one controller and then pass the same variable to view

I have two controllers ParentController and ChildController I have a variable in ParentController and i need to get that variable to ChildController and then i need to pass it to the view and one more thing is i should not use the $scope in child controller and parentController. Is it possible ?if not is there any way to use it with out $scope.
app.controller('ParentController', function($scope) {
$scope.exampleVariable = "test";
});
app.controller('ChildController', function($scope, $controller) {
var someScopeVariable = this;
$controller('ParentController', {$scope: someScopeVariable });
console.log(someScopeVariable.exampleVariable)
someScopeVariable.exampleVariable = "Updatetest";
});
Now in my html view i need to use exampleVariable
like this
<div ng-controller="ChildController as child">
<h1>{{child.exampleVariable}}</h1>
</div>
How can i get the value from parentcontroller to html view.
You can always use a service to share data between controllers.
create a service
app.service('myservice', function() {
var myVar;
this.setMyVar = function(value){
this.myVar = value
}
this.getMyVar = function(){
return this.myVar;
}
});
pass it as a dependency and you can have the value shared.
app.controller('ParentController',['$scope', 'myservice', function($scope, myservice) {
$scope.exampleVariable = "test";
myservice.setMyVar("test");
}]);
you can pass it to other controller as a dependency too and you can do a getMyVar there!!
You can use Broadcast and On in the Controller-
app.controller('ParentController', function($scope) {
var self = this;
$scope.$broadcast('exampleVariable', 'test');
});
and in child controller -
app.controller('ChildController', function($scope, $controller) {
var someScopeVariable = this;
$controller('ParentController', {$scope: someScopeVariable });
console.log(someScopeVariable.exampleVariable)
$scope.$on('exampleVariable', function(event, data) {
someScopeVariable.exampleVariable = data;
});
});
There are some ways you can achieve this.
1. Through $rootScope.
2. By Creating Service.
3. Inheriting parent controller to children controller.
2 & 3 are already provided in other answers. Follow this if you want to achieve it using $rootScope.
JS :
var app = angular.module('myApp', []);
app.controller('ParentController', function($scope, $rootScope) {
$rootScope.exampleVariable = "test";
});
app.controller('ChildController', function($scope) {
});
HTML :
<div ng-controller="ParentController">
Parent Controller : {{exampleVariable}}
<hr/>
</div>
<div ng-controller="ChildController">
Children Controller : {{exampleVariable}}
</div>
DEMO LINK.
Note : You can also override the scope variable in children controller by adding the below code in ChildController :
$scope.exampleVariable = "overriding...";

How to use service in angular.js controller?

I have created the service but i am not getting how use this service in my controller.
(function(){
'use.strict';
angular
.module('app.core')
.factory('shareBtwnCtrlr', shareBtwnCtrlrService);
/** #ngInject */
function shareBtwnCtrlrService() {
shareBtwnCtrlr = function($scope, $rootScope){
$scope.value = $rootScope.test;
}
return shareBtwnCtrlr;
}
})();
In the above code $rootScope.test is coming from one controller and now i have to use this $scope.value in another controller using this service. The another controller is like below
(function (){
'use strict';
angular.module('app.product')
.controller('ProductController', ProductController);
/** #ngInject */
//ProductController.$inject = ['$http', '$location', '$scope'];
function ProductController($http, $location, $rootScope, $scope, $localStorage, $interval, $timeout,$mdDialog, $document, shareBtwnCtrlr){
var vm = this;
}
})();
You got two modules, so dependency injector can't inject your service from app.core to app.product.
Try to create new module
var app = angular.module('app', ['app.core','app.product']);
and then
angular.module('app').factory('shareBtwnCtrlr', shareBtwnCtrlrService);
Only a service in the same module can be injected to the controllers and directives of the module.
The new module should be added to the app to expand its capabilities.
angular.module('app.core')
.factory('shareBtwnCtrlrService', function() {
var shareBtwnCtrlrService = this;
shareBtwnCtrlrService.value = function(){
//do something
}
return shareBtwnCtrlrService;
}
};
angular.module('app.product')
.factory('productService', function() {
var productService = this;
productService.value = function(){
//do something
}
return productService;
}
};
Now to use the service in the core and product modules, we create app module including both in it
angular.module('app', ['app.product', 'app.core'])
.controller('ProductController', ['shareBtwnCtrlrService', 'productService', function (shareBtwnCtrlrService, productService) {
// ...do something
}]);

How to use injected dependency in a angular service?

I am creating a custom service which logs a user in to my system. In this service, I need to use core services such as $http - How do I actually depend these to be used in my service?
My current code:
.factory('loginService', ['$http', '$rootScope', function() {
var login = function(){
console.log($http);
}
return {login : login};
}])
I call the login function from a controller like so
loginService.login();
I hoped that my console will output the $http object I injected, but it's returning undefined.
How do I access this in the correct way?
You need to add the dependencies to your function arguments:
.factory('loginService', ['$http', '$rootScope', function($http, $rootScope) {
//You can use $http and $rootScope here now
}
See the official docs for more info on Dependency Injection in angular
Services you inject need to be passed as arguments of the function:
['$http', '$rootScope', function($http, $rootScope)
By the way, you'll need to do the same where you're trying to use it:
app.controller(['loginService', function (loginService) {
loginService.login();
});
try this:
var myapp = angular.module('mainApp', []);
myapp.controller('myController', ['$scope', 'myFactory', function($scope, myFactory) {
myFactory.login();
}]);
myapp.factory('myFactory', ['$http', function($http) {
var services = {};
services.login = function() {
console.log($http);
}
return services;
}]);
View:
<div ng-app='mainApp' ng-controller='myController'></div>

Is possibile to configure a controller (like services) in AngularJS?

I have my CartDropdownController that can be configured (i.e. setting autoCloseDelay) and I'm facing the following problem: how to inject the controller in angular.run() method?
angular.module('app')
.controller('CartDropdownController', ['$scope', function ($scope) {
this.autoCloseDelay = 3000;
this.setAutoCloseDelay = function (autoCloseDelay ) {
this.autoCloseDelay = autoCloseDelay;
};
// $scope variables here...
}]);
I know that services can be injected in .run() (like $http), but my controller is not a service (and I don't know how to make it a service...).
Edit: why? I don't want my controller to depend on values/constants:
angular.module('app')
.value('config', {
cart: {autoCloseDelay: 1500}
})
.controller('CartDropdownController', [
'$scope',
'config',
function ($scope, config) {
var autoCloseDelay = config.cart.autoCloseDelay || 3000;
// ...
}
]);
docs say You can only inject instances (not Providers), and yes controller itself is also an instance, just like a service.
Now See this example:
var myApp = angular.module('myApp', []);
myApp.factory('aProvider', function() {
console.log("factory invoked");
return{
fun:function(from){
console.log("factory from"+from);
}
}
});
myApp.directive("test1", function() {
console.log("directive setup");
return {
compile: function() {console.log("directive compile");}
}
});
myApp.directive("test2", function() {
return {
link: function() {console.log("directive link");}
}
});
myApp.run(function(aProvider) {
console.log("app run");
// aProvider.fun('from run');
});
myApp.config( function() {
console.log("app config");
});
myApp.controller('myCtrl', function($scope) {
console.log("app controller");
});
And the result:
app config
(index):24 factory invoked
(index):46 app run
(index):33 directive setup
(index):35 directive compile
(index):56 app controller
(index):41 directive link
What happens here:
config block executed
factory is invoked(instances, services or factories)
run executed
directives set
controllers initialized
directives linked to the page
Now here, you see run is executed first and controllers are initialized afterwords. This is why controllers cant be injected into app.run()

How to access the $scope where the factory was injected?

Say I have a factory named MyFactory and I inject it into several controllers. How can I access the controllers scope inside the factory?
The only way I currently think of on how to do this is as follows:
app.factory('MyFactory', function() {
return function($scope) {
myPublicFunc: function() {
$scope.$on('$destroy', function() { ... });
}
}
});
app.controller('MyController1', ['$scope', MyFactory', function($scope, Myfactory) {
var factory = new MyFactory($scope);
factory.myPublicFunc();
});
But is there any other way where I can just return { } instead of function($scope) { } in MyFactory and use the factory directly (MyFactory.myPublicFunc) instead of having to create a new instance with the new keyword and still access each controller's $scope?
if you use a .service instead of .factory you will already have a singleton instance in a controller once you inject it via DI
and then you can do for example
module.service('myService', function() {
return {
myPublicFn: function() {}
}
});
and
module.controller('myCtrl', function(myService, $scope) {
$scope.publicFn = myService.myPublicFn;
});

Resources