Ternary operator no false option - ternary

I am studying Ternary operators right now and I understand most of it but want to see if this is possible.
normal ternary : (condition) ? (result true): (result false);
question is how to write one with just a true part no false;
(condition) ? (result true):;
or
(condition) ? (result true);
or
Not possible

It's just that would not make sense as expressions must represent a concrete value.
You cannot use if/else clauses as they are no expressions:
print(if (value > 0) { "yes" } else { "no" });
But you can use the ternary operator for "inline" evaluation:
print(value > 0 ? "yes" : "no");
Assume what happens if the condition is evaluated to false and there is no "result" - how should the compiler know what to print?

In JavaScript a ternary example looks like this:
const value = 1;
const result = value > 0 ? "Bigger" : "Smaller";
console.log(result);
Result: Bigger
If you don't need show "Smaller", you can try this:
const value = 1;
const result = value > 0 && "Bigger";
console.log(result);
Result: Bigger

Related

Firestore-Rules evaluation error on Timestamp Field

I wrote a firestore rule like this:
function isPublished() {
return !('publicationAt' in resource.data.keys()) ? true :
debug(debug(request.time) >= debug(resource.data.publicationAt));
}
and in my app i´m saving several datetimes just with new Date();
Now, I´d like to get a list of all items that are published - but it gives me an evaluation error - with this debug:
constraint_value {
simple_constraints {
comparator: LTE
value {
timestamp_value {
seconds: 1669108946
nanos: 684000000
}
}
}
}
timestamp_value { seconds: 1669108945 nanos: 727000000 }
Can someone give me a hint what I´m doing wrong?
While you may be tempted to think that Security Rules Language (SRL) is JavaScript because of the function() {} part, it is not. It is a special statically evaluated language that gets interpreted once without other common features like iteration.
Importantly, the SRL has no ternary operator:
<condition> ? <result-when-true> : <result-when-false>
Instead you must build your conditions as a sequence of Boolean tests making use of the available helper methods and classes.
The equivalent in basic Boolean algebra of the ternary operator (when using short-circuiting operators like && and ||) is:
(<condition> && <result-when-true>) || (NOT(<condition>) && <result-when-false>)
Substituting in the value for <result-when-true>, we can reduce down your expression using Boolean algebra laws (where the AND operator (&&) is ∧ and the OR operator (||) is ∨):
(<condition> && <result-when-true>) || (NOT(<condition>) && <result-when-false>)
// replace <result-when-true> with TRUE, as in your question
(<condition> && TRUE) || (NOT(<condition>) && <result-when-false>)
// now remove the redundant "&& TRUE" (see "Identity of ∧")
<condition> || (NOT(<condition>) && <result-when-false>)
// now distribute the OR operator (see "Distributivity of ∨ over ∧")
(<condition> || NOT(<condition>)) && (<condition> || <result-when-false>)
// now replace (<condition> || NOT(<condition>)) because it will always be TRUE (see "Complementation 2")
TRUE && (<condition> || <result-when-false>)
// now remove the redundant "TRUE &&" like before (see "Identity of ∧")
<condition> || <result-when-false>
Subsituting in the parts from your question, this leaves us with:
!('publicationAt' in resource.data.keys())
|| debug(debug(request.time) >= debug(resource.data.publicationAt))
You can also simplify 'publicationAt' in resource.data.keys() to just 'publicationAt' in resource.data (as the in operator handles what you were expecting for rules.Map objects), giving us:
!('publicationAt' in resource.data)
|| debug(debug(request.time) >= debug(resource.data.publicationAt));
This means the correct form of your SRL function would look like:
function isPublished() {
return !('publicationAt' in resource.data)
|| debug(debug(request.time) >= debug(resource.data.publicationAt));
}

What is the cause for this odd OR and ternary output [Javascript]

Hey so I am having an issue with an OR and ternary operation. I have this code here.
console.log(this.state.records)
Before: {
AllowCheck: "1"
Checked: "0"
}
const records = this.state.records.map((record) => {
return {
...record,
Checked: checked || record.AllowCheck === '0' ? '1' : '0',
}
});
console.log(records)
After: {
AllowCheck: "1"
Checked: "1"
}
When you look at the log before the ternary operation, you see that the object has a property called “AllowCheck”. You can see here that it evaluates as a 1 in the record. If you look at the function below, you’ll see a map operation that iterates over a list of records. The variable “checked” comes from a checkbox onChange operation that will evaluate as true in this situation. In the OR operation you can see that “checked” will be true, and the ternary on the right is where the “record.AllowCheck” will evaluated as a 1 from before. The ternary should result in a 0 since “record.AllowCheck” is 1. You’ll see in the after object that Checked is equal to 1. I don't know why it's not equal to two from the "checked" variables, and I really don't understand how it's equal to 1. Am I missing something? Have I been looking at this for too long? Any opinions or answers would be much appreciated, thank you.
The ternary should result in a 0 since “record.AllowCheck” is 1
Nope. The condition in this ternary operation is not what you think it is (record.AllowCheck === '0'). It's actually checked || record.AllowCheck === '0' and, since checked is truthy, it short-circuits on the first step, evaluates to true overall and that's how the ternary operator evaluates to '1'.
See the operator precedence table for more information: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#table

Handlebars doesn't render boolean variables when false

Handlebars.js has some weird behavior. It renders a boolean with a value of true as the string "true", but a value of false as "".
var booleanTestTrue = true;
var booleanTestFalse = false;
Template:
True: {{booleanTestTrue}}
False: {{booleanTestFalse}}
Renders to:
True: true
False: (empty string)
Is there any way to fix this problem? Or do I have to write a helper?
You can use a simple block helper and implement #if like the following:
{{#if isTrue}}
true
{{else}}
false
{{/if}}
If you want to print a string, you should pass a string.
false.toString();
Otherwise, yeah you would need a helper (unless you use the #if|#unless helpers to output a string).
On a side note, if you wanted to print these values for debugging purpose, use the {{log booleanTestFalse}}.
I was surprised by this, and ended up writing a simple helper for it:
Handlebars.registerHelper( 'toString', function returnToString( x ){
return ( x === void 0 ) ? 'undefined' : x.toString();
} );
You would then invoke it as follows:
True: {{toString booleanTestTrue}}
False: {{toString booleanTestFalse}}
In most scenarios you could get away with simply return x.toString(). The extra checking avoids attempting to call toString on undefined values.
I used this, similar to Barney's answer but supports null too.
Handlebars.registerHelper('toString', function (v) {
return '' + v;
});
You would then invoke it as follows:
True: {{toString booleanTestTrue}}
False: {{toString booleanTestFalse}}
However if v is an object with a pretty toString method you need to do more coding.

Simple question about operator ||

HEllo,
i try to do that in FlashBuilder (FlexProject)
protected function btn_detail_view_clickHandler(event:MouseEvent):void
{
CurrentState="Statistiques" || "PartMarche";
}
But it's not working, i guess this is not the right syntax but what's the right syntax ? Thanks
PS: i want to when the state is equal to "statistiques" or "partMarche" when i click on the button, that the current state changes to Detail view ;)
In ECMAScript languages, || is a short-circuit operator that will return the left-hand side expression result if it evaluates to a "truthy" value, or the right-hand side expression result otherwise. Non-empty strings always evaluate to truthy values, so the left-hand expression will always be returned here. The equivalent long-hand code to your example is:
if ("Statistiques")
CurrentState = "Statistiques";
else
CurrentState = "PartMarche";
This type of short circuit operator is used to set defaults to variables in certain situations:
CurrentState = PreviousState || "Some string";
In that example, if PreviousState is null or false or an empty string, CurrentState would be set to "Some string". If PreviousState is a string like "Some other string", CurrentState would be set to "Some other string".
Thanks for clarifying what you want to do. For checking what CurrentState is, you need to test it with an if condition:
if (CurrentState == "Statistiques" || CurrentState == "PartMarche")
{
// Of course, use the actual name of your detail view here
CurrentState = "DetailView";
}
Ok in fact i need to remove the .Statistiques to that code works in all the states
click.Statistiques="btn_detail_view_clickHandler(event)"
Sorry i just went too fast by myself instead of finishing the tutorial.
Your answers will prevent me to ask the next question ! thank you ;)

Simplest way to check if a string converted to a number is actually a number in actionscript

Not sure if this makes sense, but I need to check if a server value returned is actually a number. Right now I get ALL number values returned as strings
ie '7' instead of 7.
What's the simplest way to check if string values can actually be converted to numbers?
The easiest way to do this is to actually convert the string to a Number and test to see if it's NaN. If you look at the Flex API reference, the top-level Number() function says it will return NaN if the string passed to the method cannot be converted to a Number.
Fortunately, Flex (sort of) does this for you, with the isNaN() function. All you need to do is:
var testFlag:Boolean = isNaN( someStringThatMightBeANumber );
If testFlag is false, the string can be converted to a number, otherwise it can't be converted.
Edit
The above will not work if compiling in strict mode. Instead, you will need to first convert to Number and then check for NaN, as follows:
var testFlag:Boolean = isNaN( Number( someStringThatMightBeANumber ) );
Haven't tested this, but this should work:
if( isNaN(theString) ) {
trace("it is a string");
} else {
trace("it is a number");
}
If you are using AS3 and/or strict mode (as pointed out by back2dos), you will need to convert to number first in order for it to compile:
if( isNaN(Number(theString)) ) {
trace("it is a string");
} else {
trace("it is a number");
}
Most of the answers on this question have a major flaw in them. If you take Number(null) or Number(undefined) or Number(""), all will return 0 and will evaluate to "is a number". Try something like this instead:
function isANumber( val:* ):Boolean {
return !(val === null || val === "" || isNaN(val));
}
RegExp path :
function stringIsAValidNumber(s: String) : Boolean {
return Boolean(s.match(/^[0-9]+.?[0-9]+$/));
}
Here is another way to check if value can be converted to a number:
var ob:Object = {a:'2',b:3,c:'string'};
for( var v:* in ob){
var nr:Number = ob[v];
trace(ob[v]+" "+(nr === Number(nr)))
}
this will trace following:
2 true
3 true
string false
You can notice that in actionscript :
trace(int('7')); // will return 7
and
trace(int('a')); // will return 0
So except for zeros, you can actually now if a string is a number or not
this will try to convert your String to a Number, which essentially is a 64 bit floating point number:
var val:Number = Number(sourceString);
if sourceString is not a valid String representation of a Number, val will be NaN (not a number) ... you have check against that value with isNaN ... because val == NaN will return false for a reason that can't quite understand ... you can use int(val) == val to check, whether it is an integral value ...
greetz
back2dos
Put this into any function where you want only numbers to stayjoy_edit1 is a TextInput Object (spark)
//is a number check
if( isNaN(Number(joy_edit1.text)) ) {
joy_edit1.text = "";
return void;
}
function isANumber(__str:String):Boolean
{
return !isNaN(Number(__str));
}
You should use the native solution of Adobe:
parseInt and parseFloat methods.
Also read the isNaN description:
Returns true if the value is NaN(not a number). The isNaN() function
is useful for checking whether a mathematical expression evaluates
successfully to a number. The most common use of isNaN() is to check
the value returned from the parseInt() and parseFloat() functions. The
NaN value is a special member of the Number data type that represents
a value that is "not a number."
Here is a simple implementation:
function isANumber(value:String):Boolean {
return !isNaN(parseFloat(value));
}
typeof('7') == 'string'
typeof(7) == 'number'
Does that help?

Resources