calling 2 functions from 2 different controller on one click - angularjs

I have 2 controller say cont_a and cont_b which has function fun_a() and fun_b() respectively.
I have a button inside cont_a and if I click on it it should call both function, and I have no idea from where to begin with.
Thank you.

Two options, use a service or use an angular event
Service approach
app.service('funcService', function(){
this.fun_a = function (){
alert('fun_a')
}
this.fun_b = function (){
alert('fun_b')
}
}
app.controller('Ctrl_1' , function($scope,funcService){
$scope.callBothFunctions = function(){
funcService.fun_a();
funcService.fun_b()
}
});
app.controller('Ctrl_2' , function($scope,funcService){
$scope.func_b = funcService.func_b;
});
Event approach
app.controller('Ctrl_1' , function($scope,$rootScope){
$scope.fun_a = function (){
alert('fun_a');
$rootScope.$broadcast('call-fun_b');
}
});
app.controller('Ctrl_2' , function($scope){
$scope.fun_b = function (){
alert('fun_b')
}
$scope.$on('call-fun_b', function(){
$scope.fun_b();
})
});
Beyond this, question is too vague to know what best approach is. Generally using services is best way to keep controller code lean

Related

Auto trigger function throuigh service in angularjs

hi all i am using angulrajs passing one value from one controller to another controller using service it's work fine but my need is when service value change in controller 2 i get the service value in one scope when scope value change i need trigger the function it's called refresh function when service value change and that i need to call the refresh function here my fiddle
https://jsfiddle.net/ctawL4t3/10/
You can just $watch your value.storeObject. Though it's not best of the practices, but it suits this kind of feature.
$scope.$watch('value.storedObject', function(newVal) {
if(newVal !== '') {
refresh()
}
})
working fiddle (open console to see refresh function logging)
You can try to use angular default $emit, $broadcast, or try to do 2 simple functions in own service
angular.module('app').factory('StoreService', function() {
var listeners = {};
var emit = function(name, val) {
if(listeners[name]) {
listeners[name](val)
}
}
var on = function(name, callback) {
listeners[name] = callback;
}
return {
emit: emit,
on: on,
storedObject: ''
};
});
JSFiddle example
JSFiddle example $watch
JSFiddle example ng-change is better because, you can use easily debounce
you can use broadcast function for that
Please check this SO link to find the related answer
How to call a function from another controller in angularjs?
app.controller('One', ['$scope', '$rootScope'
function($scope) {
$rootScope.$on("CallParentMethod", function(){
$scope.parentmethod();
});
$scope.parentmethod = function() {
// task
}
}
]);
app.controller('two', ['$scope', '$rootScope'
function($scope) {
$scope.childmethod = function() {
$rootScope.$emit("CallParentMethod", {});
}
}
]);

Angular - Moving function into a service

I have a function that I'm now needing to use in multiple page so decided to move into a service - however its not going as I'm expecting.
So in my HTML i have:
<li ng-init="bg = underQBar(work.options)">
Then in the controller (before I moved the common function) it looked like:
$scope.underQBar = function(toWorkArray) {
//some implementation, with a return at the end
}
Now I've made my service:
function barService($window){
var self = this;
self.getBarColours = function(toWorkArray) {
//copied the implementation with the return here
}
}
And therefore trying this in my controller:
$scope.underQBar = barService.getBarColours(toWorkArray);
However this doesnt work, its not getting the parameter I'm sending from the HTML - is this a trivial fix or something wrong with the implementation?
This is the problem:
$scope.underQBar = barService.getBarColours(toWorkArray);
Here, you're assigning the result of the service function call to $scope.underQBar, when you meant to assign it the function itself.
This should work:
$scope.underQBar = barService.getBarColours;
If you want to make it more clear to the reader that it's a function, just do:
$scope.underQBar = function (toWorkArray) {
return barService.getBarColours(toWorkArray);
}
Here is a correct definition for your service :
angular.module("myModule").factory("BarService", ["$window", function($window){
var service = {};
service.getBarColours = function(toWorkArray){
//copied the implementation with the return here
};
return service;
}]);
And here is a correct way to inject the service in your controller :
angular.module("myModule").controller("controllerName", ["BarService", function(BarService){
var self = this;
self.getBarColours = BarService.getBarColours;
}]);
and here is the way to use it:
<li ng-init="bg = controllerName.underQBar(work.options)">
Explanation :
A service or a factory in angular cannot be accessed by your view. Your view can only make a call to your controllers.
If your function should have been called by many controllers, you can put this function in a global controller that will be responsible for controlling your whole view.

angularJS: Function in function

Hello I'm new in angularJS. Suitable or not to implement function inside function?
For example like this:-
$scope.loadDistrict = function(id) {
// statement
$scope.loadBasedOnYear = function(y_id) {
console.log(y_id);
// statement
};
};
If you bind method on scope, it's available from view.
From your code
$scope.loadDistrict = function(id) {
// statement
$scope.loadBasedOnYear = function(y_id) {
console.log(y_id);
// statement
};
};
loadBasedOnYear won't available until loadDistrict is called.
It's very bad pattern to follow.
It is possible but without context I don't really know why you would do this, calling $scope.loadBasedOnYear before calling $scope.loadDistrict will result in an error so be careful with such a design pattern.
Yes this is fine.
You should watch out for when the function will be executed outside of angular's cycle. E.g. if you do:
setTimeout(function() { $scope.test = 5; }, 1000);
If you need to do this then you need to wrap the function in $scope.$apply(), or use $timeout.

Extending a controller's specific functions

I have controller (say BaseCtrl) that has a number of functions attached to it. I want to extend BaseCtrl to other controllers that shares some of its functions, however, I only need a function or two (and not all of BaseCtrl's functions). I already saw some posts that demonstrates how to extend a controller, but I wonder if it's possible to extend specific functions only and how to do it?
Extending my comment:
app.controller('parentCtrl', function($scope,$rootscope) {
$rootscope.myPerent = function () {
//your code
}
});
app.controller('childCtrl', function($scope,$rootscope) {
$scope.ourPerent = function () {
$rootscope.myPerent();
}
});

Can I use a factory within another factory to join two REST requests together?

I have two factories as follows:
angular.module('categoryResource', ['ngResource', 'userResource'])
.factory('categories', function ($http, users){
var factory = {};
factory.getCategories = function () {
return $http.get('/api/userCategories');
};
factory.getCategoriesUsers = function () {
//call factory.getCategories(), parse the request to make it nice and tidy
//then call users.getUsers(), tidy them up in the same way as categories, join them together and return them all in a nice package.
};
var handleCategoriesUsers = function (data, status) {
}
return factory;
});
angular.module('userResource', ['ngResource'])
.factory('users', function ($http) {
var factory = {};
factory.getUsers = function () {
return $http.get('/api/users');
};
return factory;
});
I've already made a nice treeView with the Categories but I want to also add Users to those categories; so to this end I thought I'd just format the users into something my treeView algorithm can already work with.
My question is, Can I somehow do It within the categories factory (or even a different module/factory altogether) and just return the joined results at the same time? If yes, how? Do I need to define a handler for $http.get like I usual? then in that handler, call the other get then define a handler for that and then return the result?
I'm not 100% sure I understand the question, but have you looked at $q.all? It seems like you want to compose/combine multiple promises into a single, easy to handle package. I'd give you a description and some code samples, but egghead did it better: https://egghead.io/lessons/angularjs-q-all
Is this what you're looking for?
EDIT: In case just dumping a link is frowned upon:
var all = $q.all([one.promise, two.promise, three.promise]);
all.then(success)
function success(data) {
console.log(data);
}

Resources