$scope.$watch is not triggering when checkbox value changes - angularjs

How can I express my problem I'm not sure but
$scope.$watch is not triggering when checkbox value changes
in my project.
I've just created the below code snippet in order to show my problem to you but, unfortunately, it is working properly!!
The same approach exists in my project (of course, variable names and function names are different) but it isn't working!!
Do you have any idea about why my code can prevent to work of $scope.$watch in my project? I have tried many things but it is still not working!!
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<input type="checkbox" ng-checked="count==100" ng-true-value="100"
ng-false-value="99999" ng-model="count"> {{caption}}
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.count = 100;
$scope.$watch("count", function(a,b) {
if ($scope.count==100){
$scope.caption = ' Showing first 100 records';
} else {
$scope.caption = ' Showing all records';
}
});
});
</script>
</body>
</html>

The documentation for ng-checked clearly states that ng-checked should not be used together with ng-model.
From the Docs:
ngChecked
Sets the checked attribute on the element, if the expression inside ngChecked is truthy.
Note that this directive should not be used together with ngModel, as this can lead to unexpected behavior.
— AngularJS ng-checked Directive API Reference

Related

Getting a variable from the ng-change function angularjs

I eventually need to create a select box with 4 options - Module 1 to 4. When an option is selected I need to send the number which was selected to the controller so that it can return different datasets for a chart.
That is the end goal, however experimenting with different code pens I simplified my problem down to just trying to get a variable from an input box.
I can get the value to appear on the template but I can not access it in the controller. How can I make the function in the controller work with the passed input data?
html
<body ng-app="plunker" ng-cloak>
<div ng-controller="MainCtrl">
<h1>Hello {{name}}</h1>
<p>Start editing and see your changes reflected here!</p>
</div>
<input placeholder="Module" type="text" ng-change="moduleChange(myModule)"
ng-model="myModule" ng-model-options="{debounce: 1000}">
{{myModule}}
</body>
script.js
angular.module('plunker', []).controller('MainCtrl',
function($scope) {
$scope.name = 'Plunker';
$scope.moduleChange = function(myModule) {
alert(myModule);
console.log(myModule);
$scope.name = myModule;
}
});
I thought that I would get an alert every time I changed the input but nothing is happening. nothing is logged to the console and the $scope.name variable appears to not change.
Where am I going wrong? Thx
Also any pointers for making it work inside a select box would be great too!
plunkr
Move ng-controller="MainCtrl" to the outer element (thats the reason why the function was not fired):
<body ng-app="plunker" ng-controller="MainCtrl" ng-cloak>
You don't need to pass the value into the function, you have the value with ng-model:
<input placeholder="Module" type="text" ng-change="moduleChange()" ng-model="myModule" ng-model-options="{debounce: 1000}">
$scope.moduleChange = function() {
alert($scope.myModule);
console.log($scope.myModule);
$scope.name = $scope.myModule;
}

angular call a function and pass id

How can i pas values to a function with ng-init in a angular project?
i have tried this and it works fine:
<div ng-controller="myCtrl" ng-init="myfunction(1)">
but the problem is, when i do this
<div ng-controller="myCtrl" ng-init="myfunction({{id}})">
or
<div ng-controller="myCtrl" ng-init="myfunction(id)">
it doesn't work!!
if i show the value of {{id}} in my template i get the id: 1
so the id does exist.
what is here the problem?
As Brendan Green mentioned, if id is a scope variable you don't need to pass it to the function. Would something like this work?
$scope.myfunction = function(){
// do whatever with $scope.id
}
If you really need to use it as you are your third example should work. Here is a plunker.
Created a fiddle here: http://jsfiddle.net/frishi/HB7LU/22553/
Basically, pass in the variable itself to the function and not the interpolated value, i.e. {{boo}}
<div ng-controller="MyCtrl" ng-init="boo=2">
<div ng-click="foo(boo)">Click Me</div>
</div>
In order to use myfunction in ng-init, the function should be defined in your $scopebecause ng-init evaluate expressions whatever they may be.
So here is what you should do:
HTML:
<body ng-controller="MainCtrl" ng-init='myfunction("john");'>
<p>Hello {{name}}!</p>
</body>
JS:
app.controller('MainCtrl', function($scope) {
$scope.name = 'Mike';
$scope.myfunction = function(otherName){
$scope.name = otherName;
};
});
Example
Keep in mind that it is not recommended to use ng-init this way:
The only appropriate use of ngInit is for aliasing special properties
of ngRepeat, as seen in the demo below. Besides this case, you should
use controllers rather than ngInit to initialize values on a scope.

How to test for the existence of a function in ngIf

I'm trying to hide/show some HTML based on the existence of a function
<div ng-if="!!someFunc"> .... </div>
<div ng-if="someFunc !== undefined"> .... </div>
DEMO
Now the issue is that it doesn't matter if someFunc exists or not, it is always shown. Is there some way to make this work or should I create an other (boolean) variable on the scope ?
UPDATE: I've reproduced the issue here this time with angular v1.3.14
As others have pointed out now, in Angular 1.0, ng-if does not exist. If you have to stay with Angular 1.0, try ng-show instead.
EDIT: I wanted to make it clear that while ng-if and ng-show will both achieve what you are looking for in this case, they do behave differently behind the scenes. In short, when an ng-if expression evaluates to "false", the element will be removed from the DOM. When an ng-show expression evaluates to false, it simply changes the display property of your element. You can read more in detail here.
var myApp = angular.module('myApp', []);
function MyCtrl($scope) {
//$scope.test = function () {};
}
<div ng-controller="MyCtrl">
Is there a test function: {{!!test}}
<div ng-show="!!test">CLOSE</div>
</div>
It's something wrong with your AngularJs (too old may be).
I've updated it to new(1.3.14) and it works -
http://jsfiddle.net/HB7LU/15068/
Without any code change:
var myApp = angular.module('myApp',[]);
function MyCtrl($scope) {
//$scope.test = function () {};
}
You fiddle is using angular 1.0.1 which doesn't even contain ng-if (introduced in version 1.1.5). Update the external resource to a newer version or use one of the predefined fiddle frameworks (e.g. angular 1.2).
Both of those attempts work. Something must be wrong with your fiddle. Here's a full example:
var app = angular.module('app', []);
app.controller('Ctrl', function($scope) {
//$scope.someFunc = function() {};
});
<div ng-app="app" ng-controller="Ctrl">
<div>Some func: {{ someFunc ? 'yup' : 'nope' }}</div>
<div ng-if="!!someFunc">Has some func</div>
<div ng-if="someFunc !== undefined">Has some func</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.2/angular.js"></script>

How can I trigger angular 1.3 animation with ng-include binding to a partial

I have an ng-include which is bound to a scope variable.
I can change the included content dynamically through my own 'routing' system using this approach.
However angular animations are fired on enter and leave events and are not triggered simply when the binding changes for the ng-include.
what is the best approach to implementing this, some kind of custom directive that wraps the ng-include behaviour, or is there a simpler way to do this that I'm missing?
Here's the index html
<body ng-controller="MainCtrl">
<div ng-include="templateUrl" class="animation" ></div>
<br/><form>
<button ng-click="swapTemplate()">Swap</button>
</form>
</body>
and the controller code
$scope.templateUrl = 'page2.html';
$scope.swapTemplate = function() {
if($scope.templateUrl === 'page1.html'){
$scope.templateUrl = 'page2.html';
}
else {
$scope.templateUrl = 'page1.html';
}
}
And the plnk http://plnkr.co/edit/Oh1vKi0DCxj95qO1J23x
you need to add angular-animate.js file
<script data-require="angular-animate#*" data-semver="1.2.13" src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.3/angular-animate.js"></script>
add ngAnimate module in to main module
var app = angular.module('plunker', ['ngAnimate']);
here is the demo Plunker

Angularjs controller nesting

I'm new to angular, I've tried some testing pattern and it's ok with the $scope variable but I can't make it work for a simple controller nesting. (and avoid using the $scope variable, instead I want to use "this")
Here is my sample HTML and javascript :
<!doctype html>
<html ng-app="appTest">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script>
</head>
<body>
<div ng-controller="FirstController as first">
<div>
First is {{first.text}}
</div>
<div ng-controller="SecondController as second">
Second is {{second.text}}
</div>
</div>
<script>
var app = angular.module("appTest",[]);
function printFirst() {
this.text = "first"
}
function printSecond() {
this.text = "second";
}
app.controller("FirstController",[printFirst]);
app.controller("SecondController",[printSecond]);
</script>
</body>
</html>
In the output html the angular variables inside curly brackets are not replaced and I don't know what's going on. I've tried to install Angular Batarang for debugging but the scope console is empty.
Obviously it's a silly mistake but I don't see where I'm wrong
Ok, the answer has nothing to do with my code, I was just using a too old version of Angularjs (1.0.8).
I moved to the last version 1.3.4 and it works fine.
Access the variable using $scope.text please instead of this.text.

Resources