AngularJS undefined, null and 0 - angularjs

Consider the following code:
<div ng-controller="SomeCtrl">
<div ng-show="someVariable.someProperty">Value of someProperty is set</div>
</div>
Now, when I set in my SomeCtrl controller:
$scope.someVariable.someProperty = 1;
It will show the div, as expected. But when I set:
$scope.someVariable.someProperty = 0;
It does not, while I only want to hide it in case $scope.someVariable.someProperty is either undefined or null. Of course I could write a simple Javascript helper-function to give me the expected result, or write something like:
<div ng-show="someVariable.someProperty || someVariable.someProperty == 0">Value of someProperty is set</div>
But isn't there a more elegant way to
handle this in AngularJS?

I only want to hide it in case $scope.someVariable.someProperty is either undefined or null
In JavaScript, undefined == null, but neither == 0. No need for extra functions or an extra conditional
ng-show="someVariable.someProperty != null"

Change your logic to be something more like this then:
ng-show="someVariable.someProperty !== null && someVariable.someProperty >= 0">
That way null or undefined will be falsy.
I almost forgot that null >= 0 === true (silly Javascript :)

Put a function in the controller like this:
$scope.shouldShow = function() {
if($scope.someVariable.someProperty === null ||
$scope.someVariable.someProperty === "undefined") {
return false;
}
return true;
}
and in the html:
<div ng-show="shouldShow()">Value of someProperty is set</div>

As mentioned by #tymeJV, "0" is evaluated as false in JS, so ng-show="0" will evaluate to hiding the div.
In SomeCtrl, you could write a function which encapsulates the logic to determine whether someProperty is null or undefined and return true or false based on that evaluation.
angular.module("app")
.controller("SomeCtrl", function($scope) {
$scope.someVariable = {};
$scope.someVariable.someProperty = null;
$scope.isNullorUndefined = function(value) {
return value === null || angular.isUndefined(value);
};
});
<div ng-show="!isNullOrUndefined(someVariable.someProperty)">Value of someProperty is set</div>

Related

setting a class based on an angular property

I want to do something like this
ng-class="'notification-{{notification.severity}}' : notification.severity"
and have the result be <div class="notification-warn"></div> when the notification.severity is "warn"
currently I get <div class="notification-"></div>
EDIT: this is an example of what I want to do
https://jsfiddle.net/flashjammin/tgt3tok2/
Try this
<div ng-if="notification.severity" ng-class="'notification-{{notification.severity}}' : notification.severity == 'warn'"></div>
You can try the ternary operator to toggle between class.
Set the value of 'showNotification' in controller.
Set the values of notification.severity as whole
i.e. notification.severity = "notification-warn";
Controller:
if(notification.severity != '' || notification.severity != null){
$scope.showNotification = true;
}
else{
$scope.showNotification = false;
}
HTML:
<div ng-class="showNotification? 'notification' : notification.severity">

AngularJS forEach function - cannot get to resolve to true

I have the following code in my controller:
$scope.checkSchedule = function (value) {
var result = false;
angular.forEach($scope.shifts, function (obj) {
if (obj['PublishedEmployee.Id'] === value && result === false) {
result = true;
}
});
return result;
};
My $scope.shifts is an array of objects. Each object contains another object, PublishedEmployee and that object has a property of Id.
My goal is to iterate over the $scope.shifts objects and if the PublishedEmployee.Id property == $scope.currentId then resolve the function to be true.
In my HTML I have the following:
ng-show="checkSchedule(currentId)"
So, if the function resolves to true, the element will display. However, I'm always receiving false, what am I missing to have this resolve accordingly?
Pictures:
Your problem is that you are checking for the literal property "PublishedEmployee.Id" and not the sub property "Id" of "PublishedEmployee".
Change
if (obj['PublishedEmployee.Id'] === value && result === false)
to
if (!result && obj.PublishedEmployee && obj.PublishedEmployee.Id === value)
This will check for the existence of a PublishedEmployee property before attempting to compare its Id property.
If you're just wanting to check if any of the $scope.shifts match, you can use Array.prototype.some.
return $scope.shifts.some(function(obj) {
return obj.PublishedEmployee && obj.PublishedEmployee.Id === value;
});
In theory this will work if your data is as you say...
<div ng-repeat="item in shifts">
<div ng-show="item.PublishedEmployee.Id == currentId">
Matched
</div>
</div>

If statment on ng-click?

I need to call function on ng-click but only if $scope.currentActiveMenu = 1;.
How can i do that?
ng-click="GetAllTickets(0,25) = currnetActiveMenu==1">
or something like that?
Don't put any Condition Expression in Template, do it in the Controller.
ng-click="checkCurrentActiveMenu(currentActiveMenu)">
Controller :
$scope.checkCurrentActiveMenu = function(value) {
if (value == 1) {
GetAllTickets(0,25);
}
}
If you really need this in the template, you can use this (if the first condition isn't true, the second one will not be called):
ng-click="currentActiveMenu==1 && GetAllTickets(0,25)">
Like this:
ng-click="currnetActiveMenu === 1 && GetAllTickets(0,25)"
Create a function in your controller:
ng-click="GetAllTicketsForMenu(0,25, currnetActiveMenu)">
in your controller:
$scope.GetAllTicketsForMenu = function(val1,val2, currnetActiveMenu){
if(currnetActiveMenu === 1){
$scope.GetAllTickets(val1,val2);
}
};
You could also try a ternary:
ng-click="currnetActiveMenu==1 ? GetAllTickets(0,25) : null ">

Why am I getting different results from ng-show="!emptyArray" and ng-hide="emptyArray"?

I have always thought ngShow and ngHide act as boolean counterpart to each other. That belief, however, is shaken by the unexpected behaviour of ngShow when an empty array is involved.
Here is a demo plunker. Why isn't ng-show="!emptyArray" behaving like ng-hide="emptyArray"?
Because [] !== false. You can coerce the length value to boolean instead with !!.
<div ng-hide="!!emptyArray.length">emptyArray is falsy, so do not hide this.</div>
<div ng-show="!!!emptyArray.length">!emptyArray is truthy, so show this.</div>
Edited:
AngularJS's directive hide or show depends on the function toBoolean() for evaluating the value passed in. Here is the source code of toBoolean():
function toBoolean(value) {
if (value && value.length !== 0) {
var v = lowercase("" + value);
value = !(v == 'f' || v == '0' || v == 'false' || v == 'no' || v == 'n' || v == '[]');
} else {
value = false;
}
return value;
}
And you can verify the following code in JS console:
>var emptyArray = [];
>toBoolean(emptyArray)
false
>toBoolean(!emptyArray)
false
That explains why. Since when emptyArray is passed to the toBoolean() directly, it evaluates the correct result false. However when !emptyArray is passed to toBoolean(), it doesn't evaluate to true since !emptyArray is false itself.
Hope it helps.
ng-if and ng-show mistreats "[]" (empty array)
See: this link
[] == true
false
[] != true
true
(![]) == true
false
[''] == true
false
(!['']) == true
false
"" == true
false
"[]" == true
false
(!"[]") == true
false
Sounds its by design.
I use something like this , it works to me
ng-hide="array.length == 0"

How to bind 1/0 instead of true/false on checked property of a checkbox

<input type="checkbox" data-bind="value : 1, checked: FgActive" />
I want FgActive to be 1 and 0 instead of true and false. Is there a simple way of doing that?
The easiest thing to do is to create a ko.computed that converts the checked boolean binding to/from a 1/0 numeric.
self.fgActiveNumeric = ko.computed({
read: function () {
return self.fgActive() == 1 ? true : false;
},
write: function (newValue) {
self.fgActive(newValue ? 1 : 0);
}
});
Use it like a normal checked binding:
<input type='checkbox' data-bind='checked: fgActiveNumeric' />
You can read more about this technique here: http://knockoutjs.com/documentation/computedObservables.html
See the Fiddle
I came across a solution. I created a custom binding that works on the update, after the checked binding. Dont know if is the best solution, but worked just fine.
ko.bindingHandlers.NumChecked = {
update: function (element, valueAccesor) {
var func = valueAccesor();
if (typeof (func) == 'function' && func() == true)
func(1);
else if ((typeof (func) == 'function'))
func(0);
}
};
<input type="checkbox" data-bind="NumChecked: FgActive, checked: FgActive" />
This is how I do it, using jQuery:
var myVal = ( $('#myCheckbox').is(':checked') ) ? 1 : 0;
alert('myVal is: ' +myVal); //alerts 1 if checked, 0 if not checked
jsFiddle Demo

Resources