Call one controller method from another controller in angular js 1 - angularjs

I wanted to call closeTools() of ToolsController from PaymentAccessController but unable to do so.
Details are added in child controller. Please refer to child controller method onCancel().
//Parent Controller
(function(){
angular.module('ssuiTools').controller('ToolsController',ToolsController);
ToolsController.$inject=['$scope'];
function ToolsController($scope){
var vmTool = this;
vmTool.closeTools = closeTools;
init();
function init(){
-
-
}
function closeTools(){
$scope.toolsList = [];
$scope.showToolsContainer = false;
$scope.isMaximised = true;
$scope.isZoomedOut = false;
}
}
})();
//Child Controller
(function(){
angular.module('ssuiTools').controller('PaymentAccessController',PaymentAccessController);
PaymentAccessController.$inject=['httpService','$scope','$filter','$q'];
function PaymentAccessController(httpService, $scope, $filter, $q){
var vmPat =this;
vmPat.onCancel =onCancel;
init();
function init(){
-
-
-
}
function onCancel(){
//here i want to call closeTools() of parent controller - ToolsController
ToolsController.closeTools(); //tried different ways but didn't work
}
};
})();

In your tools controller
(function(){
angular.module('ssuiTools').controller('ToolsController',ToolsController);
ToolsController.$inject=['$scope'];
function ToolsController($scope){
var vmTool = this;
vmTool.closeTools = closeTools;
init();
$scope.$on('on-cancel-called', function (event,data) { //Catch on-cancel-called event
closeTools();
});
function init(){
}
function closeTools(){
$scope.toolsList = [];
$scope.showToolsContainer = false;
$scope.isMaximised = true;
$scope.isZoomedOut = false;
}
}
})();
And inside the child controller
(function(){
angular.module('ssuiTools').controller('PaymentAccessController',PaymentAccessController);
PaymentAccessController.$inject=['httpService','$scope','$filter','$q'];
function PaymentAccessController(httpService, $scope, $filter, $q){
var vmPat =this;
vmPat.onCancel =onCancel;
init();
function init(){
}
function onCancel(){
$scope.$emit('on-cancel-called')
}
};
})();
To learn more about $on,$broadcast and $emit please refer to this link

Related

writing a simple Angular Service

OK, I've built services before but obviously I don't actually know what makes them tick, since I can't seem to debug this ultra-simple service call:
app.js:
var gridApp = angular.module('gridApp', []);
gridApp.controller('mainController', ['$scope', '$http', 'dataService',
function($scope, dataService) {
$scope.message = 'I am Angular and I am working.';
var init = function(){
console.log(dataService.foo);
console.log(dataService.getData());
};
init();
}]);
dataService.js:
(function() {
'use strict';
angular
.module('gridApp')
.service('dataService', dataService)
dataService.$inject = [];
function dataService() {
console.log("I am the dataService and I am loaded");
var foo = 1;
function getData () {
return 2;
}
}
})();
I see this on-screen: I am Angular and I am working. so Angular is loading.
I see this in console: I am the dataService and I am loaded so the dataService is actually being loaded.
But then the console.log is:
undefined (line 8)
TypeError: dataService.getData is not a function (line 9)
What am I missing?
The previous answers are correct in that your $http injection was wrong, but you are also not attaching your service functions to the service:
function dataService() {
var dataService = this; //get a reference to the service
//attach your functions and variables to the service reference
dataService.foo = 1;
dataService.getData = function() {
return 2;
};
}
An Angular service is very simply an object class. It is also a singleton, meaning it's instantiated only once per run of your app. When the service is instantiated it is very much akin to calling the new operator on your dataService "class":
var $dataService = new dataService();
So, when you inject dataService into your controller, you are actually getting an instance, $dataService, of your dataService "class".
See this blog entry for further reading: https://tylermcginnis.com/angularjs-factory-vs-service-vs-provider-5f426cfe6b8c#.sneoo52nk
You are missing the 2nd parameter $http in the function. The named parameters and the actual parameters in function need to be the same, same order and same number. What happened before is that dataService was being assigned an $http instance and the actual dataService was not injected at all because there was no 3rd parameter to inject it into.
var gridApp = angular.module('gridApp', []);
gridApp.controller('mainController', ['$scope', '$http', 'dataService',
function($scope, $http, dataService) {
// ----was missing-----^
$scope.message = 'I am Angular and I am working.';
var init = function(){
console.log(dataService.foo);
console.log(dataService.getData());
};
init();
}]);
We have missed the second param '$http' in function. Just add the '$http' param, it should work fine
var gridApp = angular.module('gridApp', []);
gridApp.controller('mainController', ['$scope', '$http', 'dataService',
function($scope,$http, dataService) {
$scope.message = 'I am Angular and I am working.';
var init = function(){
console.log(dataService.foo);
console.log(dataService.getData());
};
init();
}]);
This is how I've been taught to set up services:
function dataService() {
var dataService = {};
var _foo = 1;
var _getData = function () { return 2; }
dataService.foo = _foo;
dataService.getData = _getData;
return dataService;
}
I believe this facilitates public/private methods/vars.
For reference, this is the full code accessing my service:
app.js:
var gridApp = angular.module('gridApp', []);
// create the controller and inject Angular's $scope
gridApp.controller('mainController', ['$scope', 'dataService', function($scope, dataService) {
// create a message to display in our view
$scope.message = 'Angular is working';
var init = function(){
getPackageData();
};
var getPackageData = function (){
return dataService.getData().then(
function successCallback(response) {
console.log(response);
},
function errorCallback(response) {
console.log(response);
}
);
};
init();
}]);
dataService.js:
(function() {
'use strict';
angular
.module('gridApp')
.service('dataService', dataService)
dataService.$inject = ['$http'];
function dataService($http) {
var dataService = {};
var _getData = function () {
return $http({
method: 'GET',
url: 'data/packages.json'
})
.then(function successCallback(response) {
return response;
},
function errorCallback(response) {
return response;
});
}
dataService.getData = _getData;
return dataService;
}
})();

How can I passing Parameter angularjs factory $http and $stateParameters

App.factory('menuService', function ($http) {
var urlBase = 'Services/MenuService.asmx/GetAllMenu';
var factory = {};
factory.getAllMenus= function () {
return $http.get(urlBase);
};
return factory;
});
Controller:
App.controller("sampleController", function ($scope, menuService) {
$scope.List = [];
var menuData=function(data, status){
$scope.List = data;
console.log($scope.List);
}
menuService.getAllMenus().success(menuData);
});
/// Working perfect...
How can i use same service by other controller?
I've tried this one but wrong...
App.controller("viewDetailMenu", function ($scope, menuService, $stateParams) {
$scope.menu = menuService.getMenu($stateParams.id);
});
Here I share image how it look..
Please help me!...
You need to have all functions/methods defined if you want to use them. You getMenu function/method is not defined so it will generate an error. Please look at below code. You can add number of functions. You factory is share by all controllers so you can use it in any controller.
App.factory('menuService', function ($http) {
var urlBase = 'Services/MenuService.asmx/GetAllMenu';
var factory = {};
factory.getAllMenus= function () {
return $http.get(urlBase);
},
factory.getMenu=function(id){
return $http.get(urlBase +"/ID="+ id) // write it according to your API.
}
return factory;
});
And then,
App.controller("viewDetailMenu", function ($scope, menuService, $stateParams) {
$scope.menu = menuService.getMenu($stateParams.id).success(function(data,status){
}).error(function(data,status){
});
});

Best way to ng-hide my headMenu from different controller

I want to hide my headmenu.
app.controller("kpiOverviewCtrl", function ($scope, $stateParams,) {
"use strict";
var setUpController = function () {
$scope.headmenu = $state.current.controller === "kpiCompareCtrl";
};
$rootScope.$on('$locationChangeSuccess', function () {
setUpController();
});
$rootScope.$on('$stateChangeSuccess', function () {
setUpController();
});
setUpController();
});
As you can see on the code it sets headmenu to true on a controller switch. It works fine. But now I want to set headmenu to true on a ng-click statment from a controller thats already been loaded.
app.controller("kpiDetailsCtrl", function ($scope, $state) {
"use strict";
$scope.loadDataForMonthView = function () {
$scope.errorNoDataForDate = false;
$scope.yearMode = false;
$scope.monthMode = true;
//Here I want to set $scope.headmenu = true;
//Other code.....
};
Any nice suggestions?
Use a broadcast. They're a great way for communication between controllers.
Create a regular function in your main controller, which you can call from within the controller itself.
app.controller('Main', function($scope) {
function setHeadMenu() {
// Set menu to true
}
$scope.$on('setHeadMenu', function() {
setHeadmenu(); // Fires on broadcast
})
});
Create an ng-click which fires a broadcast from the other controller
app.controller('Second', function($scope) {
$scope.click = function() {
$scope.$broadcast('setHeadMenu'); // Send a broadcast to the first controller
}
});
You can declare new method to $rootScope inside kpiOverviewCtrl:
app.controller("kpiOverviewCtrl", function ($scope, $stateParams, $rootScope) {
"use strict";
//your code...........
$rootScope.setUpController = setUpController;
});
And then call it from kpiDetailsCtrl controller:
app.controller("kpiDetailsCtrl", function ($scope, $state, $rootScope) {
"use strict";
$scope.loadDataForMonthView = function () {
$scope.errorNoDataForDate = false;
$scope.yearMode = false;
$scope.monthMode = true;
$rootScope.setUpController();
}
});
First dummy suggestion:
$scope.loadDataForMonthView = function () {
$scope.headmenu = true; //(or false)
}
But most likely you are using some asynchrounous call, so something like this would be better:
$scope.loadDataForMonthView = function () {
// First: you need some promise object
// the most simple is to use $http
var promise = $http({url: 'some.url', method: 'GET'});
promise.then(function() {
// the data have arrived to client
// you can hide or show menu according to your needs
$scope.headmenu = true; //(or false)
})
}
More on how $http works is in the docs https://docs.angularjs.org/api/ng/service/$http

Duplicate REST API Calls inside Angular controller

I have an angular controller. At the beginning of the controller, I want to call a REST API to initialize one object.
I am using the Angular $Resource to do it.
function () {
"use strict";
angular
.module("common.services")
.factory("hostAgentResource",
["$resource",
hostAgentResource]);
function hostAgentResource($resource) {
var brokerSvcUrl = "http://localhost:13898";
return $resource(brokerSvcUrl + "/api/HostAgent")
}
}());
hostAgentResource.query({ agentNicHash: vm.product.hostAgentNicHash }, function (data) {
vm.productDetail = data[0];
});
And here is my controller signature
angular
.module("productManagement")
.controller("ProductEditCtrl",
["productResource",
"userResource",
"hostAgentResource",
"shareDataService",
"$state",
"$http",
ProductEditCtrl]);
function ProductEditCtrl(productResource, userResource, hostAgentResource,shareDataService, $state, $http) {
var vm = this;
if ($state.params["clientId"] >= 0) {
vm.product = shareDataService.getValue("currentProduct");
vm.title = "Edit:" + vm.product.hostName;
} else
{
vm.product = {};
vm.product.clientId = -1;
vm.title = "New Desktop";
}
hostAgentResource.query({ agentNicHash: vm.product.hostAgentNicHash }, function (data) {
vm.productDetail = data[0];
});
My question is that somehow, the hostAgentResource.query was called 4 times when I load the controller. I only expect an onetime call to initialize the vm.productDetail.
Is it because I have multiple external dependency object being injected in?

How to call a controller function from a service?

i have 2 controllers who are not in the same scope or have a parent child relation.
So i want to call from controlleB a function in ControllerA. In my case its a listContoller with an addItem function and i want to call this function from a addItemController somewhere else on the page after clicking submit. i know this should work with a service, but i dont know how.
app.controller("listCtrl", ["$scope", "listSvc", function ($scope, listSvc){
$scope.list.data = listSvc.load("category");
$scope.addItem = function(newitem) {
$scope.list.data.unshift(newitem);
...
}
}]);
app.controller("addItemCrtl", ["$scope", "listSvc", function ($scope, listSvc){
$scope.addItem = function() {
listSvc.addItem($scope.newItem);
}
}]);
app.service('listSvc', function() {
return{
load: function(section){
...
},
addItem: function(item){
addItem(item); <<-- call function in listController
}
}
});
UPDATE
k is this better? i put the list.data inside my service and i watch from my controller if the list change and put it on the scope from my controller that ng-repeat can do his work... is this appraoch better? or have someone better tips for me how i should do this...
app.service('listSvc', ['$http', function($http) {
var list = {};
return {
list:{
get: function () {
return list.data;
},
set: function (data) {
list.data = data;
}
},
addItem: function(item){
var response = $http.post("/api/album/"+$scope.list.section, item);
response.success(function(){
list.data.unshift(item);
console.log("yeah success added item");
}).error(function(){
console.log("buuuh something went wrong");
});
return response;
},
load: function(section){
var response = $http.get("/api/album/"+section);
response.success(function(data){
list.set(data);
list.section = section;
console.log("yeah success loaded list");
}).error(function(){
console.log("buuuh something went wrong");
});
return response;
}
};
}]);
and in my controllers i do this
app.controller("listCrtl", ["$scope", "listSvc", function ($scope, listSvc){
listSvc.load("category");
...
$scope.$watch('listSvc.list.get()', function(data) {
$scope.list.data = data;
});
...
}]);
app.controller("addItemCrtl", ["$scope", "listSvc", function ($scope, listSvc){
...
$scope.addItem = function() {
listSvc.addItem($scope.newItem);
}
...
}]);
gregor ;)
I just solved this myself! Perhaps this may help:
The function inside of my Controller:
var timeoutMsg = function() {
vm.$parent.notification = false;
};
The function inside my Service (I had to pass in $timeout as well as the name of the function from my Controller, now it works):
// original broken code:
// this.modalSend = function(vm) {
// fixed:
this.modalSend = function(vm, $timeout, timeoutMsg) {
vm.$parent.sendTransaction = function() {
// Show notification
vm.$parent.message = 'Transaction sent!';
vm.$parent.notification = true;
$timeout(timeoutMsg, 4000);
// original broken code:
// $timeout(timeoutMsg(), 4000);
};
}
var vm = $scope

Resources