Passing Parameter to Angular Factory from controller - javascript

I couldn't pass the parameter from angular controller to factory. Can any one help me on this? It works without passing parameter but when I pass it it's not.
var app = angular.module('employee', ['ui.grid', 'ui.grid.saveState', 'ui.grid.selection', 'ui.grid.cellNav', 'ui.grid.resizeColumns', 'ui.grid.moveColumns', 'ui.grid.pinning', 'ui.bootstrap', 'ui.grid.autoResize','ui.grid.pagination']);
app.controller('EmpCtrl', ['$scope', '$http', '$interval', '$modal', '$log', 'gridService', function ($scope, $http, $interval, $modal, $log, gridService) {
$scope.LoadNextPage = gridService.LoadNextPage("5");
}]);
var gridService = function ($http, $rootScope) {
return {
LoadNextPage: function (hh) {
alert(hh);
},
gridOptions:gridOptions
};
};
app.factory('gridService', ['$http', '$rootScope', gridService]);
And this is how I use it in the view
<span id="pcNext"
class="glyphicon glyphicon-step-forward"
ng-click="LoadNextPage()">
</span>

The problem is in your controller:
$scope.LoadNextPage = gridService.LoadNextPage("5");
This means that your LoadNextPage is not a function but rather a result of the call to a function in your service. Which btw doesn't return anything but rather just displays an alert. But in your view, you're using LoadNextPage as a function call...
Change it to this so your controller's LoadNextPage will be a function that you can call from the view.
$scope.LoadNextPage = gridService.LoadNextPage;
and in your view:
<span id="pcNext"
class="glyphicon glyphicon-step-forward"
ng-click="LoadNextPage(5)">
</span>
This should work.
Note: I suspect that your gridOptions are defined somewhere outside of scope of your code that you provided in the question so that it doesn't throw and error because of the missing (likely) object. So I considered this a typo in your code and not the actual problem.
Don't want params in your view?
No problem. You can either create a wrapper function or bind it to specific parameters in your code:
// wrap
$scope.LoadNextPage = function() {
return gridService.LoadNextPage("5");
};
// bind
$scope.LoadNextPage = gridService.LoadNextPage.bind(this, 5);
Or bake the number in your service...

Issue here is gridOptions:gridOptions is not defined which throws error.
Remove ,gridOptions:gridOptions from factory.
Check snippet for working code and compare with your code.
var app = angular.module('employee', []);
app.controller('EmpCtrl', ['$scope', 'gridService', function ($scope, gridService) {
$scope.clickMe = function() {
$scope.LoadNextPage = gridService.LoadNextPage("5");
}
}]);
var gridService = function() {
return {
LoadNextPage: function (hh) {
alert(hh);
}
};
};
app.factory('gridService', ['$http', '$rootScope', gridService]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="employee" ng-controller="EmpCtrl">
<button ng-click="clickMe()">Button</button>
</div>

you not defined gridOptions function see this link:
angular.module("myApp", []).controller("myCon", function($scope, $interval, gridService){
$scope.LoadNextPage = gridService.LoadNextPage("5");
}).factory('gridService', ['$http', '$rootScope', gridService]);
function gridService($http, $rootScope){
return {
LoadNextPage: function (hh) {
alert(hh);
}
};
}
see this link

Related

Unable to call function as $rootScope is undefined

I am trying to call the function inside the controller 'Notification' when getNotification is called in the SelectNotificationCtlr. However when running this I get an Error stating that $rootScope is undefined on the line below console.log("log");. I have tried passing the $rootScope as a parameter in my getNotification function but still receive the same error.
Please see my code below, any advice or help would be really appreciated.
app.js
selectNotification.controller('selectNotificationCtlr', ['$scope', '$rootScope', 'notificationsService',
function($scope, $http, notificationsService, notificationService, $rootScope) {
$scope.getNotification = function() {
var id = $scope.selectedNotification;
notificationData = notificationsService.getNotifications();
console.log(notificationData);
console.log("log");
$rootScope.$emit("call", {});
}
}
]);
selectNotification.controller('Notification', ['$scope', '$rootScope',
function($scope, $rootScope) {
$rootScope.$on("call", function() {
$scope.parent(notificationService);
});
$scope.parent = function() {
console.log("log");
}
}
]);
Kind regards
CB
Your controller should have dependencies in the right order,
selectNotification.controller('selectNotificationCtlr', ['$scope', '$rootScope', 'notificationsService',
function($scope, $rootScope, notificationsService) {

Angular: strange behavior with ngCookies

In my Angular app
var mainApp = angular.module('mainApp', ['ngCookies']);
I've defined authCtrl controller:
mainApp.controller('authCtrl', ['$scope, $cookies',function ($scope, $http, $cookies) {
$scope.credentials = {};
$scope.signCheck = function () {
a = $cookies.getObject('session_credentials');
console.log(a);
};
}]);
If I'm removing $scope declaration from array (injection array?)
mainApp.controller('authCtrl', ['$cookies',function ($scope, $http, $cookies) {
$scope becomes undefined.
If I'm removing $cookies — $cookies becomes undefined.
If I keep them both — $injector unknown provider error.
What I'm doing wrong?
Just be sure that you indicate the services in a correct order in the injector array and the controller function params:
Angular docs says:
This is the preferred way to annotate application components. This is
how the examples in the documentation are written.
For example:
someModule.controller('MyController', ['$scope', 'greeter', function($scope, greeter) {
// ...
}]);
Here we pass an array whose elements consist of a list of strings (the
names of the dependencies) followed by the function itself.
When using this type of annotation, take care to keep the annotation
array in sync with the parameters in the function declaration.
Perhaps this controller definition will work for you:
mainApp.controller('authCtrl', ['$scope', '$http', '$cookies', function ($scope, $http, $cookies) {
$scope.credentials = {};
$scope.signCheck = function () {
a = $cookies.getObject('session_credentials');
console.log(a);
};
}]);

JavaScript angular controller get value from scope from another controller

I have school task.
We have a HTML code like this:
<html ng-app="myTest">
<head><script type="text/javascript" src="../myScript.js"></script>
</head>
<body id="tst" class="textpage" ng-controller="TestController as testcon">
<form class="" id="frm" ng-submit="doStuff()">
<div class="form-group">
{{testinfo}}
</div>
<div class="form-group">
<button type="submit" id="sbtn" name="sbtn">testSubmit</button>
</div>
</form>
</body>
</html>
Content of javascript with name myScript.js is this:
var tester = angular.module('myTest', ['ui.mask']);
tester.controller('TestController', ['$scope', '$http', '$location', '$window', function ($scope, $http, $location, $window) {
$scope.doStuff = function () {
{
$scope.testinfo = 'unknown value';
};
};
}
]);
I have option to add new javascript.
But I am not possible to get value from $scope.testninfo.
I cannot edit existing JavaScript and cannot edit HTML file. I can just add new javascript.
Is there option how to get value from $scope.testinfo in another javascript?
Thanks.
You can use broadcast
From controller 1 we broadcast an event
$scope.$broadcast('myEvent',anyData);
controller 2 will receive our event
$scope.$on('myEvent', function(event,anyData) {
//code for controller 2
});
here anyData represent your object to be passed
Use ng-model.
<div class="form-group">
<input type="text" ng-model="testinfo">
</div>
I dont think it is possible without appending the existing javascript/html. Because the $scope of the TestController cannot be accessed from another controller (file).
If you COULD append the HTML you could use the $rootscope, in that way the value, which is set by the TestController is accessible from another controller. Or you can add a Global app value. I created a fiddle which show the two options: https://jsfiddle.net/Appiez/wnyb9pxc/2/
var tester = angular.module('myTest', []);
tester.value('globalVar', { value: '' });
tester.controller('TestController', ['$rootScope', '$scope', '$http', '$location', '$window', 'globalVar', function ($rootScope, $scope, $http, $location, $window, globalVar) {
$scope.doStuff = function () {
{
$rootScope.testinfo = 'this is the new value';
globalVar.value = 'a global value';
};
};
}
]);
tester.controller('TestController2', ['$rootScope', '$scope', 'globalVar', function ($rootScope, $scope, globalVar) {
$scope.doStuff2 = function () {
{
alert($rootScope.testinfo);
alert(globalVar.value);
};
};
}
]);
This is what services are for in angular. They ferry data across controllers. You can use NG's $broadcast to publish events that contain data, but Providers, Services, and Factories are built to solve this.
angular.module('krs', [])
.controller('OneCtrl', function($scope, data){
$scope.theData = data.getData();
})
.controller('TwoCtrl', function($scope, data){
$scope.theData = data.getData();
})
.service('data', function(){
return {
getData: function(){
return ["Foo", "Bar"];
}
}
});
Here's a fiddle to help get you into the swing of things. Good luck in school!

How do I get an instance of a controller that was created by AngularJS?

I have an app based on Angular which I initialize like this:
myapp.init = (function () {
'use strict';
var angularApp = angular.module('myapp', [])
.directive('homeIterationDirective', function () {
return function (scope, element, attrs) {
var isTopCard = scope.$last ? true : false;
cards.initSingleSwipe(element.get(0), function (event) {
// I want to call indexPageController.onSwiped(event) here!
}, isTopCard);
};
})
.directive('homeDirective', function () {
return function (scope, element, attrs) {
cards.initPanel(element, function (event) {
// I want to call indexPageController.onButtonPressed(event) here!
});
};
});
angularApp.factory('AjaxService', myapp.services.AjaxService);
angularApp.controller('IndexPageController', ['$scope', '$http', '$sce', 'AjaxService', myapp.pages.IndexPageController]);
}());
My controller looks like this:
myapp.pages.IndexPageController = function ($scope, $http, $sce, MyService) {
'use strict';
var somevalue = {};
this.onSwiped = function (event) {
doSomethingWith(event, somevalue);
};
this.onButtonPressed = function (event) {
doSomethingWith(event, somevalue);
};
};
In the 2 directives homeIterationDirective and homeDirective I have 2 callbacks cards.initSingleSwipe and cards.initPanel. Within these callbacks I want to call public methods of my controller but I don't have the instance available that Angular created from IndexPageController. How can I achieve this?
Use (inject) a service (and not a Controller) if you want "to call a public method" from another place, possibly from another Controller.
angularApp.controller('MyController', function ($scope, IndexPageService) {
IndexPageService.blah();
}));
Controller is intended to receive and modify a $scope (adding methods, variables..etc). The $scope can than be used inside the template (html) that use the controller itself.
If you want to call some controller code within the Angular context but in another place, then you should probably move that calling code to a service and then call the service method directly.
But if you want to call that method outside Angular context then, you can achieve that like this:
<div id="foo" ng-controller="IndexPageController">
<!-- code -->
</div>
Now, you can write something like this:
angular.element(document.getElementById("foo")).scope().blah();
I also think you should use a service for this. But if you still need to call one controller from another you can use $controller service
(function() {
var app = angular.module('myApp', ['ngRoute']);
app.config(function ($routeProvider) {
$routeProvider.when("/first", {
templateUrl: 'app/view.html',
controller: 'firstCtrl'
}).when("/second", {
templateUrl: 'app/view.html',
controller: 'secondCtrl'
})
.otherwise({
redirectTo: "/first"
});
});
app.controller('firstCtrl', function ($scope) {
$scope.name = "first Controller";
$scope.nameToUpper = function () {
return $scope.name.toUpperCase();
}
});
app.controller('secondCtrl', function ($scope, $controller) {
var newScope = $scope.$new();
$controller('firstCtrl', { $scope: newScope });
$scope.name = newScope.nameToUpper() + 'from second ctrl';
});
}())
and view is
<div>
{{name}}
</div>

Angularjs how to call a function of a controller from another controller

I am trying to split a big controller. The way to go would be through factories, but since I am changing the DOM I should do it through controllers.
Then, what I am trying to achieve is to call a function defined in Cntrl2 from Cntrl1.
The example
html
<body ng-app="app">
<div ng-controller='Cntrl1'>
{{message}}
</div>
</body>
js
var myModule = angular.module('app', []);
angular.module('app').controller('Cntrl1',
['$scope', '$q', '$timeout', 'Share_scope',
function ($scope, $q, $timeout, Share_scope) {
Share_scope.process();
$scope.message = 'started';
}]);
angular.module('app').controller('Cntrl2',
['$scope', '$q', '$timeout', 'Share_scope',
function ($scope, $q, $timeout, Share_scope) {
Share_scope.x = function() {
alert('done');
}
}]);
angular.module('app').factory('Share_scope',
['$window', '$q',
function($window, $q) {
var x;
return {
process: function() {
return x;
},
};
}]);
The demo http://jsfiddle.net/T8rgv/7/
What I would expect is to define "var x" of the factory as the function of Cntrl2, and then execute this function through the factory when I call it from Cntrl1.
So, how to make this work? Is this approach correct? Or should I just change the DOM from a factory?
Cheers,
Gerard
Not knowing where in relation Cntrl2 is to Cntrl1, I would use emit or broadcast somewhat like this. Note from past experience I don't think it's a good idea to use two or more different modules in the same page.
var myModule = angular.module('app', []);
angular.module('app').controller('Cntrl1',
['$scope', '$q', '$timeout', 'myFactory',
function ($scope, $q, $timeout, myFactory) {
$scope.$emit('messageEvt','started');
myFactory.process().then(function() {
$scope.$emit('messageEvt','ended');
});
}]);
angular.module('app').controller('Cntrl2',
['$scope', '$q', '$timeout', $rootScope,
function ($scope, $q, $timeout, $rootScope) {
$rootScope.$on('messageEvt',function(e,msg) {
$scope.message = msg;
}
}]);
angular.module('app').factory('myFactory',
['$window', '$q','$timeout',
function($window, $q,$timeout) {
var x;
return {
process: function() {
var deferObj = $q.defer();
$timeout(function() {
deferObj.resolve(x);
});
return deferObj.promise;
},
};
}]);
I think better way to do this is by having factory maintain the model and both controllers updating it when needed.
I updated the fiddle to http://jsfiddle.net/hh5Cy/2/
angular.module('app').factory('Share_scope',
['$window', '$q',
function($window, $q) {
var x;
return {
getProcess: function() {
return x;
},
setProcess: function(value){
x = value;
}
};
}]);
Please let me know if I understood you wrongly.

Categories

Resources