How to check if a scope variable is undefined in AngularJS template? - angularjs

How to check if a scope variable is undefined?
This does not work:
<p ng-show="foo == undefined">Show this if $scope.foo == undefined</p>

Here is the cleanest way to do this:
<p ng-show="{{foo === undefined}}">Show this if $scope.foo === undefined</p>
No need to create a helper function in the controller!

Using undefined to make a decision is usually a sign of bad design in Javascript. You might consider doing something else.
However, to answer your question: I think the best way of doing so would be adding a helper function.
$scope.isUndefined = function (thing) {
return (typeof thing === "undefined");
}
and in the template
<div ng-show="isUndefined(foo)"></div>

Corrected:
HTML
<p ng-show="getFooUndef(foo)">Show this if $scope.foo === undefined</p>
JS
$scope.foo = undefined;
$scope.getFooUndef = function(foo){
return ( typeof foo === 'undefined' );
}
Fiddle: http://jsfiddle.net/oakley349/vtcff0w5/1/

Posting new answer since Angular behavior has changed. Checking equality with undefined now works in angular expressions, at least as of 1.5, as the following code works:
ng-if="foo !== undefined"
When this ng-if evaluates to true, deleting the percentages property off the appropriate scope and calling $digest removes the element from the document, as you would expect.

If foo is not a boolean variable then this would work (i.e. you want to show this when that variable has some data):
<p ng-show="!foo">Show this if $scope.foo is undefined</p>
And vise-versa:
<p ng-show="foo">Show this if $scope.foo is defined</p>

If you're using Angular 1, I would recommend using Angular's built-in method:
angular.isDefined(value);
reference : https://docs.angularjs.org/api/ng/function/angular.isDefined

You can use the double pipe operation to check if the value is undefined the after statement:
<div ng-show="foo || false">
Show this if foo is defined!
</div>
<div ng-show="boo || true">
Show this if boo is undefined!
</div>
Check JSFiddle for demo
For technical explanation for the double pipe, I prefer to take a look on this link:
https://stackoverflow.com/a/34707750/6225126

As #impulsgraw wrote. You need to check for undefined after the pipes:
<div ng-show="foo || undefined">
Show this if foo is defined!
</div>
<div ng-show="boo || !undefined">
Show this if boo is undefined!
</div>
https://jsfiddle.net/mjfz2q9h/11/

try this
angular.isUndefined(value);
https://docs.angularjs.org/api/ng/function/angular.isUndefined

<p ng-show="angular.isUndefined(foo)">Show this if $scope.foo === undefined</p>

Related

Hide a div when ng-hide function is executed and set to true

I have a div as follows
HTML
<div ng-hide="checkStatus()">Show only if checkstatus is false</div>
Javascript
$scope.data = 23;
$scope.checkStatus() {
if($scope.data === undefined){
return false;
}
else return true;
}
If i execute this, it says data is undefined. Can someone let me know how to pass this variable to the checkStatus() function. Also this 'data' variable is dynamic and can change frequently.
I want the div to keep an eye on this 'data' variable and show or hide depending on its value.
Can someone let me know how to achieve this.
Just use the scope variable directly in the ng-hide expression:
<div ng-hide="data !== undefined">
$scope.data is undefined<br>
</div>
<div ng-show="data === undefined">
Maybe you should do something about that!!
</div>
The ng-hide and ng-show directives evaluates the AngularJS expression every digest cycle and shows or hides the element if the expression is truthy.
The DEMO on JSFiddle.
Change your javascript to:
$scope.data = true;
$scope.checkStatus = function() {
return $scope.data;
}

How to call $scope.$apply() using "controller as" syntax

I am trying to limit my use of $scope in my controllers as much as possible and replace it with the Controller as syntax.
My current problem is that i'm not sure how to call $scope.$apply() in my controller without using $scope.
Edit: I am using TypeScript 1.4 in conjunction with angular
I have this function
setWordLists() {
this.fetchInProgress = true;
var campaignId = this.campaignFactory.currentId();
var videoId = this.videoFactory.currentId();
if (!campaignId || !videoId) {
return;
}
this.wordsToTrackFactory.doGetWordsToTrackModel(campaignId, videoId)
.then((response) => {
this.fetchInProgress = false;
this.wordList = (response) ? response.data.WordList : [];
this.notUsedWordList = (response) ? response.data.NotUsedWords : [];
});
}
being called from
$scope.$on("video-switch",() => {
this.setWordLists();
});
And it's (the arrays wordList and notUsedWordList)
is not being updated in my view:
<div class="wordListWellWrapper row" ng-repeat="words in wordTrack.wordList">
<div class="col-md-5 wordListWell form-control" ng-class="(words.IsPositive)? 'posWordWell': 'negWordWell' ">
<strong class="wordListWord">{{words.Word}}</strong>
<div class="wordListIcon">
<div class="whiteFaceIcon" ng-class="(words.IsPositive)? 'happyWhiteIcon': 'sadWhiteIcon' "></div>
</div>
</div>
<div class="col-md-2">
<span aria-hidden="true" class="glyphicon-remove glyphicon" ng-click="wordTrack.removeWord(words.Word)"></span>
</div>
</div>
Along the same lines of $apply, is there another way of calling $scope.$on using Controller as?
Thanks!
To answer the question at hand here, you can use $scope() methods in a controller when using the controller-as syntax, as long as you pass $scope as a parameter to the function. However, one of the main benefits of using the controller-as syntax is not using $scope, which creates a quandary.
As was discussed in the comments, a new question will be formulated by the poster to review the specific code requiring $scope in the first place, with some recommendations for re-structuring if possible.

Set Default Value to ng-bind in HTML

I'd like to set a default value to scope, which is picked up by ng-bind. I am doing this like:
<button>Show <span data-ng-bind="data.text" data-ng-init="data.text = 'All';"></span> Names</button>
In this example, the span is set to innerHTML = 'All' when the page loads.
However, I was hoping there might be a way to do this without requiring the use of ng-init, maybe something like:
<button>Show <span data-ng-bind="data.text = 'All';"></span> Names</button>
In your controller:
$scope.data = {};
$scope.data.text = "All";
Your markup:
<button>Show <span data-ng-bind="data.text"></span> Names</button>
Or, if you want to skip the controller code (courtesy of Kohjah Breese' comment):
<button>Show <span data-ng-bind="data.text || 'All'"></span> Names</button>
Presumably there will be some code elsewhere in your controller that will toggle this value, but for the purposes of initializing, that should do.
EDIT: Alternately, as tymeJV points out in the comments (ng-cloak added so {{}} syntax doesn't display to users):
<button>Show <span ng-cloak>{{data.text || "All"}}</span> Names</button>
The || operator works also in ngBind like in pure JavaScript:
<span ng-bind="myVariable || 'My default value'"></span>
This outputs myVariable if the variable is filled, otherwise the alternative 'My default value' is used.
from angularjs doc :
The only appropriate use of ngInit is for aliasing special properties of ngRepeat [...] Besides this case, you should use controllers rather than ngInit to initialize values on a scope.
So i guess initializing data.text in your controller is fine for angularjs

To pass a javascript variable to ng-click

My example:
<button ng-click="action()" >Hello World</button>
Status : <span >{{foo}}</span>
<script>
var status= Math.random()*1000;
</script>
I want to pass a javascript variable status to action(). Is this possible?
function Mycontroller($scope,$window){
var status = $window.status//works
$scope.action = function($window){
//$window -is undefined;
//var status = $window.status
debugger
$scope.foo='default value for foo' + status;
}
}
Example 2:
window.status= Math.random()*1000;
<button ng-click="action(window.status)" >Hello World</button>
$scope.action = function($status){
// $status - is undefined ...Why??
}
Thank you very much.
No, it's not possible. Expressions use variables that are exposed on the scope. They can't access global variables (i.e. attributes of window), unless of course the window itself is exposed on the scope (using action(window.status), provided you have called $scope.window = $window before).
As JB Nizet said, you cant access the window or other global variables directly in an expression (like the one inside ng-click), only the scope. So window will return undefined in an expression. But, as HarishR said, you can access window in your controller, or a controller method, as his code shows.
But, if you really want to set it and pass it from the view, you can do an ng-init.
<div ng-controller="myController" ng-init="status = 1000">
<button ng-click="action(status)">Hello World</button>
Status : <span>{{foo}}</span>
</div>
see plunker: http://plnkr.co/edit/OWsLjAlLB4II2jGaKupN?p=preview
note that u cant access Math in the ng-init expression, as its a global variable but not on the scope.
try below
$scope.action = function(){
var status = $window.status
}
you dont need to receive $window in $scope.action...
why are you getting it as undefined is because, you are not passing it from HTML
<button ng-click="action()" >Hello World</button>
and actually you dont need to pass it from html and you are trying to receive it in your controller...

implementation of ngShow

Had this working earlier, now it doesnt respond accordingly.
In my html:
<div ng-click="setFalse();" ng-show"emptyspotslist">No results</div>
Controller:
$scope.setFalse = function () {
$scope.emptyspotslist = !$scope.emptyspotslist;
console.log($scope.emptyspotslist);
}
Default value of $scope.emptyspotslist = true.
The DIV doesnt hide, after clicking. Function gets called though.
Probably something really simple i'm overlooking.
You should have a = after ng-show attribute
Old
<div ng-click="setFalse();" ng-show"emptyspotslist">No results</div>
New
<div ng-click="setFalse();" ng-show="emptyspotslist">No results</div>
Your HTML is malformed...
ng-show="emptyspotslist"
You're missing an equals =.

Resources