AngularJS controller scope - javascript

I have a controller:
appControllers.controller('MeetingListController', ['$scope', '$route', '$location', function($scope, $route, $location){
console.log($scope.go);
$scope.progressRun = function($event){
$scope.go = true;
};
});
I don't undersand because when go variable changes value in progressRun function,
console.log doesn't show right value and it called before and after progressRun function.

Simply move your console.log() after you change the go variable in the progressRun() function...:
appControllers.controller('MeetingListController', ['$scope', '$route', '$location', function($scope, $route, $location) {
$scope.go = 'initial value you want to assign to this variable';
$scope.progressRun = function($event) {
$scope.go = true;
console.log($scope.go);
};
}]);
UPDATE:
If you want to log the variable value anytime it changes (even when it's value should be changed outside progressRun() function, use:
$scope.$watch('go', function() {
console.log($scope.go);
});
Just after go variable initialization (as correctly #Shreevardhan suggestes).

Either log the value after changing
$scope.go = true;
console.log($scope.go);
Or, use $watch on the variable
$scope.$watch('go', function() {
console.log($scope.go);
});
PS: $watch will log each time the value changes.

Related

Angular: Not able to access variables in controller using service

I am trying to share a variable between a controller and a function. But i get an error from the controller, saying this:
TypeError: Cannot read property 'getSet' of undefined
I have gone through numerous tutorials, but don't know where am I going wrong.
My service code is like this:
app.service('shareData', function() {
var selected = ["plz", "print", "something"];
var putSet = function(set) {
selected = set;
};
var getSet = function() {
return selected;
};
return {
putSet: putSet,
getSet: getSet
};
});
I am able to reach selected from my function defined like this:
setDisplay = function($scope, $mdDialog, shareData) {
console.log(shareData.getSet()); // this is working
$scope.selected = shareData.getSet();
$scope.hide = function() {
$mdDialog.hide();
};
$scope.cancel = function() {
$mdDialog.cancel();
};
$scope.answer = function(answer) {
$mdDialog.hide(answer);
};
};
My controller is like this:
app.controller('topicController', ['$scope', '$http', '$mdDialog', 'shareData',
function ($scope, $http, $mdDialog, $mdToast, shareData) {
console.log(shareData.getSet()); // NOT WORKING
}]);
You had extra $mdToast in your topicController controller's factory function, you need to remove it.
The reason behind it was not working is, currently you had 4 dependency mentioned in array like ['$scope', '$http', '$mdDialog', 'shareData', function & then you are using its instance inside the function next to DI array. Inside that function you had actually 5 dependencies where $mdToast extra. So behind the scene what happening is $scope of function hold an value of '$scope' DI array likewise you go right to left. But when it comes to $mdToast(in controller function) it was holding a value of 'shareData'(of DI array) & then the next parameter shareData get nothing.
app.controller('topicController', ['$scope', '$http', '$mdDialog', 'shareData',
function ($scope, $http, $mdDialog, shareData) { //<--removed $mdToast
console.log(shareData.getSet());
}
]);
NOTE: You are using DI inline array annotation, so the sequence in which dependency are injected in array, in same sequence you should
inject then in underlying factory function.

angular "controller as syntax" "this" data

I dont understand what I am missing
I dont get result on html i think this problem managing with controllerAs syntax
note: I can see the result in console console.log(this.movie); - its from controller
app.js
var app = angular.module('mfApp',['ngRoute', 'appControllers']);
app.config(function($routeProvider){
$routeProvider.
when('/:detail',{
templateUrl: 'template/detail.html',
controller : 'detailCtrl' ,
controllerAs: 'movieAs'
}).otherwise({
redirectTo: '/'
});
});
controller.js
var mfControllers = angular.module('appControllers', []);
mfControllers.controller('detailCtrl', ['$scope', '$routeParams', 'appServices', function($scope, $routeParams, appServices){
this.movie = [];
this.id = $routeParams.detail;
appServices.homeSearch(this.id).success(function(response){
this.movie = response;
console.log(this.movie);
// Yes, I do get array result in console
});
}]);
html - template/detail.html
My try
{{movieAs.Title}}
{{movieAs.movie.Title}}
{{movie.movieAs.Title}}
{{movie.Title}} {{title}}
mfControllers.controller('detailCtrl', ['$scope', '$routeParams', 'appServices', function($scope, $routeParams, appServices){
var me = this;
me.movie = [];
me.id = $routeParams.detail;
appServices.homeSearch(me.id).success(function(response){
me.movie = response;
console.log(me.movie);
// Yes, I do get array result in console
});
}]);
EDIT
In Javascript functions are stored as objects, so from your callbeck method inside succeess, you call this which refers to the method that you are running and not to the controller scope.
It is best practice to store the reference to the controller in a variable which can be accessed by the callback methods. me is quite an arbitrary name but widely used to refer as the parent caller. https://github.com/johnpapa/angular-styleguide
The problem is due to wrong this reference.
var mfControllers = angular.module('appControllers', []);
mfControllers
.controller('detailCtrl', ['$scope', '$routeParams', 'appServices', function($scope, $routeParams, appServices) {
var vm = this;
vm.movie = [];
vm.id = $routeParams.detail;
appServices
.homeSearch(vm.id)
.success(function(response) {
// vm !== this; here
vm.movie = response;
console.log(vm.movie);
});
}]);
A good practice when using controllerAs syntax is to assign this to vm at the very beginning of a controller. It holds the reference of the controller correctly.
That is necessary because of javascript function scoping. It will be long to explain it here, but the gist of it is that function creates a new scope, this inside a function will be different. Todd Mott has a very great write up on this.

AngularJS : watching Service properties

Take the following plunk as an example:
http://plnkr.co/edit/vKFevXhhSprzFvesc6bG?p=preview
var app = angular.module('plunker', []);
app.service('SomeService', ['$rootScope', function ($rootScope) {
var service = {
value: false
}
return service;
}]);
app.controller('MainCtrl', ['$scope', 'SomeService', function($scope, SomeService) {
$scope.value = SomeService.value;
//$scope.$watch(function () { return SomeService.value; }, function (data) { $scope.value = data; });
}]);
app.controller('SecondaryCtrl', ['$scope', 'SomeService', function($scope, SomeService) {
$scope.toggleValue = function () {
SomeService.value = !SomeService.value;
}
}]);
2 controllers and a service, 1 controller (SecondaryCtrl) updates a property on the service and the other controller (MainCtrl) references this property and displays it.
Note the $watch expression commented out in MainCtrl - with this line uncommented, everything works as expected but my question - is it necessary? Shouldn't the watch be implicit or am I doing something wrong?
When you assign the value of SomeService.value to your scope variable, you are creating a copy of the variable which is a distinct object from the value inside SomeService. By adding the watch expression you were simply keeping the two variables (the one in the scope and the one in SomeService) synchronised.
The easiest way to go about this is not to copy the value, but create a reference to the service itself. So in MainCtrl
$scope.someService = SomeService;
and in your html
Value: {{someService.value}}
this way you are actually binding to the value inside SomeService.

AngularJS $rootScope variable exists, but not accessible

I set a $rootScope variable in one of my modules and now want to access that same $rootScope variable in another module. Thus far I can see that in both modules the variable has been set properly, but when I try accessing the variable in $rootScope, I only get undefined.
How can I access this variable without doing a factory/service workaround? The variable is really simple and $rootScope should suffice for what I need. I've put some generic sample code below to illustrate the issue:
file1.js
var app = angular.module('MyApp1', []);
app.controller('Ctrl1', ['$scope', '$rootScope', function($scope, $rootScope) {
$scope.myFunc = function() {
$rootScope.test = 1;
}
}
file2.js
var app = angular.module('MyApp2', []);
app.controller('Ctrl2', ['$scope', '$rootScope', function($scope, $rootScope) {
$scope.need_to_access_this = $rootScope.test; // undefined
console.log($rootScope); // returns JS object w/ test property set to 1
}
I was just stuck in the same problem when I figured out that you have define those properties for $rootScope before the controllers or services load. So what I did was set inital values when the application runs. In your case it will be like:
app.run(function($rootScope){
$rootScope.test="variable";
})
`
In Ctrl1 the $rootScope.test value is set inside the $scope.myFunc.
The problem is that you aren't calling that function, so the test property in $rootScope is never set.
You need to call $scope.myFunc(); in Ctrl1 or set $rootScope.test = 1; dirrectly in the Controller:
app.controller('Ctrl1', ['$scope', '$rootScope', function($scope, $rootScope) {
$scope.myFunc = function() {
$rootScope.test = 1;
};
$scope.myFunc();
}
or
app.controller('Ctrl1', ['$scope', '$rootScope', function($scope, $rootScope) {
$rootScope.test = 1;
}
EDIT:
The above suggestions still remain valid, thus you need to call myFunc().
But the problem with your code is that Ctrl1 belongs to MyApp1 and Ctrl2 belongs to MyApp2.
Every application has a single root scope (docs here)
You will need to create Ctrl2 as a controller of MyApp1:
angular.module('MyApp1')
.controller('Ctrl2', ['$scope', '$rootScope', function($scope, $rootScope) {
$scope.need_to_access_this = $rootScope.test; // undefined
console.log($rootScope); // returns JS object w/ test property set to 1
}]);

data obtained from $http service cant be obtained from ng-click

Here is a part of my controller:
function($scope, $http, $stateParams, $timeout, $q, $ionicPopup, $ionicActionSheet){
$http.get('topics/' + $stateParams.subTopicId + '.json').
success(function(data, status,header, config) {
$scope.questions = data;
});
}
Now here is a part of my view:
<button ng-click="someFunc('{{questions[qNum].opt1}}')">
{{questions[0].opt1}}
</button>
In the above view {{questions[0].opt1}} works perfectly. But when passed as an arg to ng-click it becomes empty.
And again in my controller:
function someFunc(aValue){
alert(aValue); // Empty
}
Why is the value of the variable aValue empty.
On the other hand if, I directly declare $scope.questions inside my controller like this:
$scope.question = [
{ ... }
];
Then someFunc displays the value of the variable correctly. What is going on here?
What am I doing wrong?
Try this:
<button ng-click="someFunc(questions[qNum].opt1)">
Also, you are explicitly binding to element 0 when showing the property, but in your ng-click you are using a variable qNum, so be sure that is defined.

Categories