Adding function to controllers in AngularJs - angularjs

I'm trying to add function to controller in angularJS, the way I think should be working but sadly not.
Here is my code.
//this is working.
$scope.adddata = function () {
$scope.names.push({name:$scope.newdata.name,city:$scope.newdata.city});
//$scope.names.push($scope.newdata);
}
//this is not working
function adddata() {
$scope.names.push({name:$scope.newdata.name,city:$scope.newdata.city});
//$scope.names.push($scope.newdata);
}
$scope.adddata = adddata();
Both functions above are in the definition of controller, hence $scope variable is available.
Can I only use $scope.functionname = functionname(){....}
or I can create a function and later assign it to controller / scope.

Do $scope.adddata = adddata; (no parentheses). Using the parentheses will assign the result of calling adddata() to the scope variable, which is undefined (adddata() does not return a value).

This would work:
$scope.adddata = adddata;
instead of:
$scope.adddata = adddata();
Don't invoke the function, pass a reference to it.

Related

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 share variable between functions

Within a controller, I'd like to share data between two functions. For example:
controllers.controller('rightDrawerCtrl', function ($scope, $http) {
$scope.shared_id;
$scope.getId = function () {
// get the id via $http, using a secondary id to retrieve the shared_id
}
$scope.useId = function () {
// use the shared_id to make a different api call
}
});
In this example however, when useId() is called, shared_id is undefined.
I presume this is because useId was 'created' while shared_id was undefined, so hasn't been notified of the new value.
The only way I've found to fix this is by using two controllers: Share data between AngularJS controllers
Is there a better way to do this, using only 1 controller?
$scope.shared_id;
After the above statement the shared_id variable of $scope should be undefined - because you haven't assigned it any value.
Despite this the variable is still accessible inside any scope functions because $scope is global for them. And don't forget that you should access it like $scope.shared_id in all the places.
However if you initialize it in the following manner:
$scope.shared_id = 'no id';
.. it would not return undefined.
You can initialize this variable via ng-init too.
Call userId() function when getId() function get result from $http request.
Looks like I simply had to wrap the variable assignment in $scope.$apply
$scope.$apply(function() {
$scope.shared_id = 1234;
});
You can use like this with this is much easier.
var self = this;
this.shared_id;
$scope.getId = function () {
console.log(self.shared_id) ;
}
$scope.useId = function () {
console.log(self.shared_id) ;
}

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.

how to pass values between functions in the same scope

I have 2 functions in the same controller and I am trying to pass the a value from one function to another. But I am getting an error TypeError: Cannot read property 'activeDataset' of undefined
Here is my code:
angular.module('daModule').controller("Controller1",Controller1);
Controller1.$inject = ['$scope', '$timeout'];
function Controller1($scope, $timeout) {
var ct = this;
ct.datasetName = "demo";
...
ct.activeDataset = function activeDataset(){
return ct.datasetName;
};
}
Here is my other function in the same file
function fn1(Controller1) {
...
var currentDataSet = Controller1.activeDataset();
...
}
Don't know where I am going wrong.
There are a couple of things going wrong here.
One is that the functions Controller1 and fn1 are being defined on the global name space. If another module were to use the same function names, there would be problems. We call this global name space pollution and it should be avoided.
The second problem is that in Controller1 the value of this is not defined until after the function is called. And when it is called, it is set to the local context of when it was called. Attaching properties to this in a function call does not make them available as a global property of the function. That is why you are getting "activeDataset undefined" in fn1.
To answer your question of how to pass values between functions in the same scope: The functions need to be inside the controller and they should put those values on the $scope.
angular.module("myApp").controller("myController", [$scope, myController($scope){
$scope.datasetName = "demo";
$scope.activeDataSet = function(){
return $scope.datasetName;
};
$scope.fn1 = function() {
return $scope.activeDataSet();
};
}]);

how to access parents scope from ng-click

I need to pass the value of $scope.correct into the checkAnswer function but it keeps coming up undefined. ng-click only seems to understand it's own scope. What am I doing wrong?
angular.module('Tutorials', ['functions']).controller('getAnswers', function ($scope, $element){
$scope.verbs = conjugate(conjugationsets[tutorial_number][questionnum]);
$scope.correct = $scope.verbs.conjugations[0].text;
$scope.randomizeAnswers = function () {
fisherYates($scope.verbs.conjugations);
}();
$scope.checkAnswer = function (answer, correct){
checkanswer($scope, answer, correct);
}
});
You can use $scope.$parent to access the parent scope.
$scope.checkAnswer = function (answer){
checkanswer($scope, answer, $scope.$parent.correct);
}
Note: I haven't gone through the complete problem to see whether there is an better way to solve the problem

Resources