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

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.

Related

AngularJS Proper way to pass variables

I would like to make them global so I can use [color] and [shape] throughout the whole script. I will need each one to update independently but as I continue to add to the site I am going to need to use both together.
Live preview
Example does not work: $scope.shapeSelected = response.data[color][shape];
Example does work: $scope.shapeSelected = response.data.blue[shape];
var app = angular.module("computer", ['ngRoute'])
.config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/main', {
controller: 'MainCtrl'
}).
otherwise({
redirectTo: '/main'
})
}])
.controller('MainCtrl', ['$scope', '$http', function($scope, $http) {
$scope.colorType = function(color) {
$http.get('stuff.json').then(function(response) {
$scope.colorSelected = response.data.type[color];
});
}
$scope.shapeType = function(shape) {
$http.get('shapes.json').then(function(response) {
$scope.shapeSelected = response.data[color][shape]; // <--- [color] is not getting pulled in on this function.
var resultsColorShape = $scope.shapeSelected; // <--- I would like to be able to store this incase i need it later.
console.log('resultsColorShape');
});
}
}]);
You don't have to pass argument to your functions. if you defined ng-model="Color" you can use $scope.Color in your javascript code:
change in html:
ng-change="colorType()"
ng-change="shapeType()"
and js to:
$scope.colorType = function() {
$http.get('stuff.json').then(function(response) {
$scope.colorSelected = response.data.type[$scope.Color];
});
}
$scope.shapeType = function() {
$http.get('shapes.json').then(function(response) {
$scope.shapeSelected = response.data[$scope.Color][$scope.Shape];
});
}
If your question is about passing the variables or sharing the data properly across functions then this should help you.
In your scenario. As the ng-change functions are assigned.
When the ng-change function is triggered if you don't have a ng-model try to save the new value that is the passed parameter in the $scope so as to access it across all the other functions in that controller.
If you have a ng-model declared for your element then just use the attribute for the ng-model as the reference variable . e.g: ng-model="xyz" then $scope.xyz would give you the desired value of the element.
This is how you can access the element value accordingly

Assign value to controller variable asyncronously - AngularJS

I get data from remote request by companiesData.getCompanies() and put it into controller variable.
The controller does not wait for promise resolution, figuring the response array empty.
JS controller :
angular.module('X.Exh', [])
.controller('ExhibitorsController', function($scope, $state, $stateParams, companiesData) {
this.companies = [];
companiesData.getCompanies().then(function(response) {
this.companies = response.data;
console.log(this.companies); // working very well
});
});
HTML:
<ion-alpha-scroll ng-model="Exh.companies" key="name" display-key="name" subheader="true" use-complete-alphabet="true">
<!-- Basically the ion alpha scroll is just doing a ng-repeat for every item, it is not the problem here -->
Not waiting for the HTTP request, Exh.companies figures empty. (of course if I don't do this.companies = []; at the beginning of my controller, my HTML says that Exh.companies is undefined.
How do I get data properly?
this inside the unnamed function does not influence original this.companies:
angular
.module('X.Exh', [])
.controller('ExhibitorsController', function($scope, $state, $stateParams, companiesData) {
var vm = this;
vm.companies = []; // you can omit this but for documentation and code clear you can declare it;
companiesData.getCompanies().then(function(response) {
vm.companies = response.data;
console.log(vm.companies); // does not point to local this.companies but to the caller context.
});
});
Please note that vm. runs when you use controllerAs pattern.
Alternatively you can simply access $scope variable:
angular
.module('X.Exh', [])
.controller('ExhibitorsController', function($scope, $state, $stateParams, companiesData) {
$scope.companies = []; // you can omit this but for documentation and code clear you can declare it;
companiesData.getCompanies().then(function(response) {
$scope.companies = response.data;
console.log($scope.companies); // does not point to local this.companies but to the caller context.
});
});

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.

AngularJS controller scope

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.

Angular Infinite $digest Loop

I am working on a site where you can search a food, and see if its a fruit, a vegetable, or neither (because I'm bored). I decided to use Angular, even though I'm pretty new to it.
I started getting this error: $rootScope:infdig
Infinite $digest Loop
That's may or may not be the exact phrasing or the error, because the page lags out so much, I can't open the Javascript console.
This my result view controller:
app.controller('resultController', ['$scope', '$routeParams', '$http',
function($scope, $routeParams, $http) {
$scope.result = $routeParams.query;
$scope.whatIsIt = function() {
$http.get('json/foods.json').success(function(data) {
var lists = JSON.parse(data);
var itIsA = 'uuggghhhhh';
if (lists['fruit'].contains($scope.result)) {
itIsA = 'fruit';
} else if (lists['vegetable'].contains($scope.result)) {
itIsA = 'vegetable';
}
});
}
}]);
Heres my app module:
var app = angular.module('fruitOrNot', [
'ngRoute'
]);
app.config(['$routeProvider' ,
function($routeProvider) {
$routeProvider.when('/', {
templateUrl: 'layouts/fruit-search.html',
controller: 'searchController'
}).when('/:query', {
templateUrl: 'layouts/result.html',
controller: 'resultController'
});
}]);
And here is layouts/result.html:
<h1>{{ result }}</h1>
<p>{{ result }} is a {{ whatIsIt() }}</p>
So I am wondering what could be causing that $digest loop error, or how to find out, because I can't use the console. Thanks!
The whole project is here on Github as well.
The problem that you were having was that you were setting a field on the scope, which implicitly calls $digest and lays out the template again. But, laying out the template makes the http request again, and then changes the scope, which calls $digest. And that is the infinite loop.
You can avoid this by ensuring that the http request never gets triggered during a layout of the template.
A more angular correct way of implementing your app would be to extract your GET request into a proper service and then injecting your service into the controller.
Then in the controller, you make the service call, like this:
app.controller('resultController', ['$scope', '$routeParams', 'whatsitService',
function($scope, $routeParams, $http) {
$scope.result = $routeParams.query;
whatsitService.doit().then(function(result) {
$scope.whatsit = result;
}
})
;
Your template would look like this:
<h1>{{ result }}</h1>
<p>{{ result }} is a {{ whatsit }}</p>
The problem is you trying to call a function and publish the return value directly and the value that you are trying to return is out of scope. You need to put that value in scope.
Code snippet:
app.controller('resultController', ['$scope', '$routeParams', '$http',
function($scope, $routeParams, $http) {
$scope.result = $routeParams.query;
$scope.itIsA = "";
$scope.whatIsIt = function() {
$http.get('json/foods.json').success(function(data) {
var lists = JSON.parse(data);
var itIsA = 'uuggghhhhh';
if (lists['fruit'].contains($scope.result)) {
$scope.itIsA = 'fruit';
} else if (lists['vegetable'].contains($scope.result)) {
$scope.itIsA = 'vegetable';
}
});
}
}]);
and in the HTML Template:
p>{{ result }} is a {{itIsA}}</p>
Infinite $digest Loop can happen in this below case if you have bound an expression to it like : {{events()}}
and
$scope.events = function() {
return Recording.getEvents();
}
But not in the below case. even if you have bound {{events}}
$scope.events = Recording.getEvents();
The reason is in the first angular suppose the value is changing in every digest loop and it keeps updating it. In second one it simply wait for the promise.
It is happening because of in your angular expression '{{ whatIsIt() }}' in
"{{ result }} is a {{ whatIsIt() }}" you are calling a function that returns a different value each time invoke thus causing a new digest cycle which in turn invokes the function.
I think you should bind the result of whatIsIt() to a value and then use that value in template. check this out https://docs.angularjs.org/error/$rootScope/infdig

Categories