'f' character is considered as true in a ng-show - angularjs

When using angular, I had a very strange issue:
<div ng-app>
<textarea ng-model="resp" placeholder="Response"></textarea>
<a ng-show="resp">Respond</a>
</div>
Fiddle
When writing something into the textarea, the Respond link is shown.
However, strangely, when writing the letter 'f', the Respond button doesn't show.
A workaround for this is to use the condition resp.length>0, but I wonder why the letter 'f' behaves in a special way.

Actually 'f' is considered as false.
AngularJS uses the toBoolean function internally to evaluate ng-show / ng-hide expressions.
You should get the same behaviour for "f", "false", "0", "n", "no" and "[]".
You can read more about it here: https://github.com/angular/angular.js/issues/1229.
This is angular's toBoolean function:
function toBoolean(value) {
if (typeof value === 'function') {
value = true;
} else 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;
}
Update:
In AngularJS 1.3+ this behaviour has been removed.
Quote: Due to bdfc9c02, values 'f', '0', 'false', 'no', 'n', '[]' are no longer treated as falsy. The only JavaScript values that are treated as falsy by the expression parser are now: false, null, undefined, NaN, 0 and "".

My recommendation would be to check to see if resp is an empty string. Since your textarea is a string value if the string is not empty then your respond text will be displayed.
<div ng-app>
<textarea ng-model="resp" placeholder="Response"></textarea>
<a ng-show="resp != ''">Respond</a>
</div>

Check out using strict checks for conditions. 'F', 'f', 'N', 'n', '0' also don't work in your fiddle. They are considered to be shortcuts for 'false'. Typing out 'false' also fails to show the 'Respond' button.

It's just the opposite, "f" is treated as false. Note that so are all the following:
"F"
"false"
"FALSE"
"FaLsE"
" faLse "
""
" "
" "
(i.e., case and leading/trailing whitespace do not matter)
However, partial words (e.g., "fa", "fal", "fals") are not.

Related

Dollar sign and quotes in return component

i create a use state in my react component like that:
const [loading, setLoading] = React.useState(false);
and in one project in return of component i saw something like this
<ListItemButton sx={{ color: `${loading && 'yellow'}` }}>
I can't find how that `${x && 'x' }` syntax works
Can someone explain to me or show me the documentation of this?
In this case `${loading && 'yellow'}` is the same as loading && 'yellow'
Strings surrounded in backticks ` are called template literals. It allows you tu put variables in strings.
`I'm ${name}. I'm ${age} years old.`
&& operators just means 'take the first falsey element and return it. If no falsey element is found, returns the last one.
0 && "" && "Banana" will return 0
"Banana" && "" && 0 will return ""
"Banana" && 1 && 2 will return 2
It's logical AND ( && ) operator, and next thing will execute incase if true condition
let yellow = true;
console.log( yellow && "Yellow color" )
let blue = false;
console.log( blue && "Blue color" )
Just simple plane javascript template literals
`${loading && 'yellow'}`
Will become
'yellow'
or
''
Depending on loading

AngularJS ng-if with a true or false object value

Not entirely sure why this isn't working. I'm trying to hide a col is the value of driveThru is false OR equals to 'N'.
ng-if="location.driveThru === false || location.driveThru === 'N'"
However the === false isn't working and I cant determine why.
if its a boolean change as ,
"!location.driveThru' || location.driveThru === 'N'
and === with string enclosed in quotes if its a string a follows,
ng-if="location.driveThru === 'false' || location.driveThru === 'N'"

How to tell apart partially filled or invalid input of type datetime-local from the empty one?

Is there a way to know that user entered invalid date and/or time into datetime-local type of <input> as opposed to him not entering anything?
I would like to treat no input as a sign user wants to reset/remove datetime being edited.
I'm using input['datetime-local'] from AngularJS – https://docs.angularjs.org/api/ng/input/input%5Bdatetime-local%5D.
You can check the state of a datetime-local like so:
<input id="dte" type="datetime-local">
<script>
var myDate = document.getElementById("dte");
myDate.addEventListener("blur", function() {
console.log("valueMissing : " + myDate.validity.valueMissing);
console.log("badInput : " + myDate.validity.badInput);
console.log("valid : " + myDate.validity.valid);
console.log("value : " + myDate.value);
});
</script>
There are other values you can check, but these should fit the requirements you mention:
Value not entered:
valid == false && badInput == false && valueMissing == false && value == ''
Value entered (but not valid):
valid == false && badInput == true && valueMissing == false && value == ''
Value entered (and valid):
valid = true && badInput == false && valueMissing = false && value == 'whatever date you entered'

ng-show expression: comparing multiple strings using ||

Can someone please explain why this works:
<div ng-repeat="fruit in fruits">
<span ng-hide="fruit.type == 'apple' || fruit.type == 'banana'">
{{fruit.type}}
</span>
</div>
Renders:
pear lemon
But this doesn't:
<div ng-repeat="fruit in fruits">
<span ng-hide="fruit.type == 'apple' || 'banana'">
{{fruit.type}}
</span>
</div>
Renders:
// nothing
In Javascript (and most languages I know), comparisons aren't communicable. For every comparison (in this case equality), you unfortunately need a full statement.
In fruit.type == 'apple' || 'banana',
1. fruit.type == 'apple' is evaluated.
2. After that, it || compares the result of that to 'banana', which in Javascript is a truthy value ('' is the only "falsy" string, all other strings are "truthy").
In essence, you end up with fruit.type == 'apple' || TRUE, which will always trigger ng-hide.
in this case its a bad expression fruit.type == 'apple' || 'banana'
|| are used in javascript for "OR" and define a default value to a variable when some reference values is undefined or null for example:
var name = null || "mottaman85";
consolog.log(name);
"mottaman85"
function test(nombreV){
var name = nombreV || "mottaman85";
console.log(name)
}
test();
"mottaman85"

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"

Resources