how to pass values between functions in the same scope - angularjs

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();
};
}]);

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 service returns full object, but returns undefined when i try to access property

UPDATE 2:
I found out where the problem was coming from and I left out the important part.
I'm setting the property in the first controller INSIDE this
$rootScope.$on('anEvent', function (event, data) {
InjectedService.setToken(data.value);
})
But I can't grab it from outside that callback scope. The event that is listened for depends on an $http request so I'm guessing that is the problem. Are there any workarounds to this?
UPDATE:
The order of controllers are the other way around so that the code in secondController is actually being called first in my actual app. I have reordered them accordingly
Question:
I'm trying to grab the services specific property but when I try to grab the service property, I get undefined (using a getter function or not). But when I try to grab the full service, I get everything with the correct property and value.
main.js
angular.module('myApp', ['myModule', 'myServices'])
.controller('firstController', ['InjectedService', function(InjectedService) {
InjectedService.setProperty('Hello World')
}])
othermodule.js:
angular.module('myModule', [])
.controller('secondController', ['InjectedService',
function (InjectedService) {
console.log(InjectedService); // Full object with property == 'hello world'
console.log(InjectedService.property); // I get undefined
console.log(InjectedService.getProperty()); // I get undefined
// interesting to note:
InjectedService.setToken('A different string');
console.log(InjectedService.property); // I get 'A different string'
console.log(InjectedService); // Full object with property == 'Hello World' which was set in second controller
}])
services.js:
angular.module('myServices', function
.service('InjectedService', function(){
var Service = this;
Service.setProperty = function (value) {
Service.property = value;
}
Service.getProperty = function () {
return Service.property;
}
Service.unsetProperty = function () {
Service.property = null;
}
return Service;
})
It seems to me a scope problem, but the variable isn't a primitive type. Any suggestions?

Adding function to controllers in 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.

$resource inside in Controller function

I have an issue when putting $resource request inside of Controller function. It works directly from the controller, but doesn't inside the function.
Maybe someone know why? Thanks!
angular.module('Vote', ['ngResource']);
function VotesController($scope, $resource) {
$scope.simple = $resource('url'); // works
$scope.some_item = $scope.simple.get();
$scope.upvoteQuestion = function($scope, $resource) {
$scope.simple = $resource('url'); // gets error: undefined
$scope.some_item = $scope.simple.get();
}
}
The way you define your function upvoteQuestion means that it takes 2 arguments ($scope and $resource). You need to remove that:
angular.module('Vote', ['ngResource']);
function VotesController($scope, $resource) {
$scope.simple = $resource('url'); // works
$scope.some_item = $scope.simple.get();
$scope.upvoteQuestion = function() {
$scope.simple = $resource('url'); // gets error: undefined
$scope.some_item = $scope.simple.get();
};
}
It's a scope problem.
If you define your function with those arguments but don't actually give them when you call the function they'll be set as undefined and that's why you get that error.
If you declare the function without those arguments, as they're not set in the function, it will look for them in the parent scope (the Controller scope) and then find them.

Resources