Call function from another controller - javascript

How can I call function loadTable from another controller?
app.controller('tableCtrl', ['$scope', function (scope) {
scope.loadTable = function() {
//some code
};
});
app.controller('secondCtrl', ['$scope', function (scope) {
scope.buttonClick = function() {
//call loadTable from tableCtrl
};
});

Try $emit-$on(publish-subscribe) mechanism.
app.controller('tableCtrl', ['$scope', function (scope) {
scope.loadTable = function() {
//some code
};
$rootScope.$on('load-table', function (event, arg1, arg2) {
// now trigger the method.
scope.loadTable();
});
});
app.controller('secondCtrl', ['$scope', function (scope) {
scope.buttonClick = function() {
//call loadTable from tableCtrl
//emit the event
$rootScope.$emit('load-table', 'arg1', 'arg2');
};
});

You should perhaps use a service such as
app.factory('tableService', [function () {
return {
loadTable : function() {
//some code
}
};
});
app.controller('tableCtrl', ['$scope', 'tableService', function (scope, tableService) {
});
app.controller('secondCtrl', ['$scope', 'tableService', function (scope, tableService) {
scope.buttonClick = function() {
tableService.loadTable();
};
});
Your tableCtrl would then need to save any data using another function on the service.

Related

Testing Angular modalInstance within the same controller

I'm using the ui-bootstrap modal window and I'm trying to test a method that fires that modal window. My controller:
app.controller('AddProductController', ['$scope', 'ProductsService', '$uibModal', function ($scope, ProductsService, $uibModal) {
$scope.product = {};
$scope.searchCategories = function () {
ProductsService.getRootCategories().then(function (data) {
$scope.categories = data.data;
});
$scope.modalInstance = $uibModal.open({
animation: $scope.animationsEnabled,
templateUrl: 'categoryContent.html',
controller: 'AddProductController',
scope: $scope
});
$scope.modalInstance.result.then(function (category) {
$scope.searchCategory = null;
$scope.product.category = category;
}, function () {
});
};
$scope.ok = function(){
$scope.modalInstance.close($scope.product.category);
};
$scope.cancel = function(){
$scope.modalInstance.dismiss();
}]);
And my test:
describe("Products Controller", function () {
beforeEach(function () {
module('productsController');
});
beforeEach(function () {
var ProductsService, createController, scope, rootScope,
module(function ($provide) {
$provide.value('ProductsService', {
getRootCategories: function () {
return {
then: function (callback) {
return callback({data: {name: 'category1'}});
}
};
},
});
$provide.value('$uibModal', {
open : function(){
return {
then: function (callback) {
return callback({data: {name: 'category1'}});
}
};
}
});
return null;
});
});
describe('AddProductController', function () {
beforeEach(function () {
inject(function ($controller, _$rootScope_, _ProductsService_) {
rootScope = _$rootScope_;
scope = _$rootScope_.$new();
ProductsService = _ProductsService_;
createController = function () {
return $controller("AddProductController", {
$scope: scope,
});
};
});
});
it('calling searchCategories should make $scope.categories to be defined', function () {
createController();
expect(scope.categories).not.toBeDefined();
scope.searchCategories();
expect(scope.categories).toBeDefined();
});
});
});
All my tests pass,except this one, where I get TypeError: $scope.modalInstance.result is undefined.
Any clues?
It seems you're not defining result in your mock modal. Try something like this:
$provide.value('$uibModal', {
open: function () {
return {
result : {
then: function (callback) {
return callback({ data: { name: 'category1' } });
}
}
};
}
});

angular controller can't see function declared in directive

Here is the html:
<div class="col-lg-8" ng-controller="usersCtrl">
<scrollable height="180" ts-attach-spinner class="list-group">
</scrollable>
</div>
Here is the directive:
(function() {
'use strict';
angular
.module('angle')
.directive('tsAttachSpinner', tsAttachSpinner);
tsAttachSpinner.$inject = ['$window'];
function tsAttachSpinner($window) {
var directive = {
link: link,
restrict: 'A'
};
return directive;
function link(scope, element, attrs) {
function spinnerOff() {
element.className = element.className + " whirl standard";
}
function spinnerOn() {
element.className = element.className.replace(" whirl standard", "");
}
scope.spin = function (promises) {
return $q.all(promises).then(function (eventArgs) {
spinnerOff();
});
}
}
}
})();
Here is the controller:
(function () {
'use strict';
angular
.module('angle')
.controller('usersCtrl', usersCtrl);
usersCtrl.$inject = ['$scope', 'usersSvc'];
function usersCtrl($scope, usersSvc) {
$scope.title = 'Users';
activate();
function activate() {
var promises = [getUsers()];
$scope.spin(promises);
}
function getUsers() {
return usersSvc.getUsers().then(function (data) {
return $scope.users = data;
});
}
}
})();
As you can see, I declare the spin function and attach it to the scope in the ts-attach-spinner directive. However, I am getting "undefined is not a function", when I call $scope.spin in the controller.
All advice appreciated, thanks in advance.

How to call my own function inside an Angular Directive?

I'd like to call "myFunc()" inside my angular directive, how might I do this?
myApp.directive("test", function () {
return {
restrict: 'A',
template: "<div class='box'></div>",
myFunc: function() {
console.log('myFunc');
},
link: function ($scope, element, attrs) {
element.bind('click', function () {
myFunc(); //<------------- doesn't work
});
}
} // of return
});
You can't define the function as a property of your return value in your call to directive. It either needs to be defined before your return:
myApp.directive('test', function() {
var myFunc = function() {
console.log('myFunc');
};
return {
restrict: 'A',
template: '<div class="box"></div>',
link: function($scope, element, attrs) {
element.bind('click', myFunc);
}
};
};
Or the same way inside of your link function.
Just to play around :)
var app = angular.module('myApp', []);
app.controller('MainController',function() {
});
app.directive('one', function() {
return angular.extend({}, app.directive, {myfunct:function(){
alert('hello');
}});
});
app.directive('two', function(oneDirective) {
return {
link:function($scope,$element){
console.log(oneDirective[0].myfunct)
$element.on('click',oneDirective[0].myfunct);
}
};
});
or use the method binding "&":
app.directive('myDir', function() {
return {
scope: {
callback: "&"
},
link:function($scope,$element){
element.bind('click', function () {
$scope.evalAsync(function() {
$scope.callback({param1: value, param2: value2});
})
});
}
};
});
Usage:
<my-dir callback="myControllerMethod(param1, param2)"></my-dir>

Call a method from one controller defined inside directive in another controller : AngularJS

I have a directive in which controller exists, where i have a function. I need to call that function from another controller.
Directive :
angular.module('test.directives').directive("manageAccess", function() {
return {
restrict: "E",
replace: true,
templateUrl: "template/test.html",
controller: function($scope, $element, $http) {
$scope.getRoles = function() {
console.log('hi');
};
}
};
});
$scope.getRoles method is the method i need to call from different controller.
Controller:
angular.module("test.controllers").controller("testController", function($scope, $http) {
$scope.getUsers = function() {
// i need to call getRoles method here
}
});
How can i do that?
Please help,
Thanks.
You can use AngularJS Service/Factory
I put the getRoles function within the factory for the API which can be injected anywhere.
Working Demo
var RolesModule = angular.module('UserRoles', []);
RolesModule.factory('RolesAPI', function() {
return {
getRoles: function() {
this.roles = 'my roles';
console.log('test');
}
}
});
angular.module("test.controllers",['UserRoles'])
.controller("testController",function($scope,$rootScope,RolesAPI, $http) {
$scope.getUsers = function() {
RolesAPI.getRoles();
}
});
angular.module('test.directives',['UserRoles'])
.directive("manageAccess", function() {
return {
restrict: "E",
replace: true,
templateUrl: "template/test.html",
controller: function($scope, $element, $http) {
}
};
})
Try following
angular.module('test.directives').directive("manageAccess", function() {
return {
restrict: "E",
replace: true,
scope: {getRoles: '='},
templateUrl: "template/test.html",
controller: function($scope, $element, $http) {
$scope.getRoles = function() {
console.log('hi');
};
}
};
});
controller
angular.module("test.controllers").controller("testController", function($scope, $http) {
$scope.getUsers = function() {
// i need to call getRoles method here
$scope.getRoles()
}
});
in html
<manage-access get-roles="getRoles"></manage-access>
If the function is not dependent on the directive elements, move that to a service pass it to both directive and the testcontroller.

Testing angular services with controllers

I have my custom angular service, which has one method that handles with $scope.$watch, is it possible to unit test it?
angular.module('moduleName', []).factory('$name', function () {
return {
bind: function ($scope, key) {
$scope.$watch(key, function (val) {
anotherMethod(key, val);
}, true);
},
...
};
});
Solution that I've found seems to be very easy and nice:
beforeEach(function () {
inject(function ($rootScope) {
scope = $rootScope.$new();
scope.$apply(function () {
scope.value = true;
});
$name.bind(scope, 'value');
scope.$apply(function () {
scope.value = false;
});
});
});
beforeEach(function () {
value = $name.get('value');
});
it('should have $scope value', function () {
expect(value).toBeFalsy();
});

Categories