How to create inline if without else case - dart

Does Dart support a syntax to have an inline if without an else case? I sometimes find myself in a situation to create a flutter layout where this might be really helpful
new Row(children: <Widget>[
new Text(item.name),
item.name2 != null ? new Text(item.name2) : new Container(),
]
In this example the empty container is unnecessary so I was hoping for something like this:
new Row(children: <Widget>[
new Text(item.name),
item.name2 != null ? new Text(item.name2),
]

there is no inline if without else
but in your case you're using if only to check only if it's null or not
dart have :
x = someVar ?? 0
here dart checks if someVar == null ? if true sets x value to 0, if false sets it to someVar value
but flutter will never let you add null to it's widget tree, so your can't use it in row/col

You can do this:
myVar == null ? 0 : myVar
If myVar is null then is 0, else then myVar

If you need to call a function you can use like this:
String s; //null
s == null ? print("if shorthand working") : {};
For variable assignment:
String c = "not null value";
String b; //null
var a = b ?? c;
Now a = c.
Visual Studio Code tip: add this to ignore linting for a line
// ignore: unnecessary_statements

In general, the "inline if" can be written in darts as follows:
<condition> ? <expression 1> : <expression 2>
So that if <condition> evaluates to True, then <expression 1> is returned and otherwise <expression 2>.
For example:
result = myVar == null ? 0 : myVar ;
// if myVar is null -> result = 0
// if myVar is not null -> result = myVar

There is actually plans to include a similar feature into the Dart language itself.
For a preview of how it would look like, take a look at this article by Remi
https://medium.com/flutter-community/quick-tip-sync-a-taste-of-the-future-9be4cd6993f4
And some accompanying Github issues
https://github.com/flutter/flutter/issues/17862
https://github.com/dart-lang/language/issues/47
https://github.com/dart-lang/language/issues/78

Related

Dart - Functional Difference Between Conditional Operator vs. If Statement

Why does this work:
var myAnimal = (1 == 1)? 'Cat' : 'Dog'; //OK
myList.forEach((element) => (1 == element)? print('1') : print('Not 1')); //OK
But this doesn't?
var myAnimal = if(1 == 1) 'Cat'; else 'Dog';
//Expected an identifier, but got 'if'
myList.forEach((element) => if(1 == element) print('1'); else print('Not 1'));
//Expected an identifier, but got 'if'
I've been treating it like a given but I don't actually know why.
Because one is a statement (if) and other is an expression (ternary).
A statement "does" something, while an expression evaluates to a value.
The => in your function acts similarly to a return keyword.
While you can do something like: return print('statement'); . You can't return two of those statements: return: print('statement'); print('statement');

? operator to avoid NoSuchMethodError in dart

I saw a video of someone try to avoid NoSuchMethodError by using ? operator . here's the code:
/*1*/ void main () {
/*2*/ var v = vu() ;
/*3*/ var f = v.casting() ;
/*4*/ f.tbu ;
/*5*/}
show error on line 4
Unhandled exception: NoSuchMethodError: The
getter 'tbu' was called on null. Receiver: null Tried calling: tbu
but he used the ? operator :
/*1*/ void main () {
/*2*/ var v = vu() ;
/*3*/ var f = v.casting() ;
/*4*/ f?.tbu ;
/*5*/}
run without problem .
My question is what is the ? operator ??
The question mark placed before the dot allows conditional property access, which guards against trying to access a property or method of an object that might be null:
myObject?.someProperty
is equivalent to the following:
(myObject != null) ? myObject.someProperty : null
This is similar to optional chaining in JavaScript.

Strange behavior of ternary operator

I observed strange behavior, in clean "test" application I have this simple controller:
(Grails 2.5.0, Java Oracle 8u45, GNU/Linux Debian 7)
package test
class DiController {
def ok() {
double d = 0d
int i = (int)d
def r = []
r << i
if (true) {
r << i
}
else {
r << d
}
if (false) {
r << i
}
else {
r << d
}
render r.toString()
}
def bug() {
double d = 0d
int i = (int)d
def r = []
r << i
r << (true ? i : d) // why Integer will be serialized like Double ?
r << (false ? i : d)
render r.toString()
}
}
/test/di/ok renders [0, 0, 0.0], but /test/di/bug renders [0, 0.0, 0.0].
It seems that ternary operator converts the result value, but I haven't observed such conversion in Groovy console. Is this Grails specific?
(Graeme Rocher marked this as "not a bug" here: https://github.com/grails/grails-core/issues/8994, so it should be known behavior)
EDIT: I used older Groovy (1.8.6) for tests "out of Grails", Groovy 2.4.3 has described behavior (gives [0, 0.0, 0.0]), so it has really nothing to do with Grails.
I believe that's because Groovy tries to find a common ground for incompatible types. This is an example of various ternary operators uses:
println ((true ? (0 as Integer) : (0.0 as Float)).class)
println ((true ? (0 as Float) : (0.0 as Double)).class)
println ((true ? (0 as Integer) : (0 as Long)).class)
println ((true ? (0 as Integer) : (0 as Byte)).class)
and that's how Groovy compiles this into Java
var1[1].callCurrent(this, var1[2].callGetProperty(true?(Float)ScriptBytecodeAdapter.castToType((Integer)ScriptBytecodeAdapter.asType(Integer.valueOf(0), Integer.class), Float.class):(Float)ScriptBytecodeAdapter.asType($const$0, Float.class)));
var1[3].callCurrent(this, var1[4].callGetProperty(true?(Double)ScriptBytecodeAdapter.castToType((Float)ScriptBytecodeAdapter.asType(Integer.valueOf(0), Float.class), Double.class):(Double)ScriptBytecodeAdapter.asType($const$0, Double.class)));
var1[5].callCurrent(this, var1[6].callGetProperty(true?(Long)ScriptBytecodeAdapter.castToType((Integer)ScriptBytecodeAdapter.asType(Integer.valueOf(0), Integer.class), Long.class):(Long)ScriptBytecodeAdapter.asType(Integer.valueOf(0), Long.class)));
var1[7].callCurrent(this, var1[8].callGetProperty(true?(Integer)ScriptBytecodeAdapter.asType(Integer.valueOf(0), Integer.class):(Integer)ScriptBytecodeAdapter.castToType((Byte)ScriptBytecodeAdapter.asType(Integer.valueOf(0), Byte.class), Integer.class)));
In all cases it does a lot of type conversions just to agree both true/false result branch and make them return the same type. Surprisingly this is the case only for numerical values. Other values are treated differently.
println ((true ? ("s") : (0 as Byte)).class)
println ((false ? ("s") : (0 as Byte)).class)
println ((true ? (new Date()) : (0 as Byte)).class)
gets translated into Java like
var1[9].callCurrent(this, var1[10].callGetProperty(true?"s":(Byte)ScriptBytecodeAdapter.asType(Integer.valueOf(0), Byte.class)));
var1[11].callCurrent(this, var1[12].callGetProperty(false?"s":(Byte)ScriptBytecodeAdapter.asType(Integer.valueOf(0), Byte.class)));
var1[13].callCurrent(this, var1[14].callGetProperty(true?var1[15].callConstructor(Date.class):(Byte)ScriptBytecodeAdapter.asType(Integer.valueOf(0), Byte.class)));
It doesn't answer why that happens but answers how that happened. At least I hope so.

ternary works different in local and heroku

I have this method it's very simple and almost all of the time the isTrue param should be false and return "2".
def test(isTrue = false)
isTrue ? 1 : 2
end
this works fine in my dev env but when I push it to heroku suddenly it starts returning as if it is true, and Im absolutly positive that its false. I think it possibly be checking if the var is nil ( or something like that)
I changed the ternary to:
isTrue == true ? 1 : 2
And it corrects the problem, I don't understand why this happens.
Can someone explain it?
thanks!
This is definitely wrong:
isTrue = true ? 1 : 2
It sets the variable isTrue to true and uses the result of that statement (true) as the input of the ternary operator, so this will always return true.
Change it to:
isTrue == true ? 1 : 2
Regarding the differences between development and production mode: check that you really feed booleans into the method and not integers (0 or 1), strings ('0', '1', 't', 'f', 'y', 'n', etc) or nil.
isTrue = true ? 1 : 2
this will always return 1 as Mark Meeus commented.
= is the assignment operator in ruby, used to make assign a variable a given value.
==, however is a comparison operator.
so with your code as it is currently, you're assigning "isTrue = true" and then telling the code to return 1 if isTrue is true.

Operator ?? null coalescing in XNA 4 inside if statement

How can I fix my code under this text?
//puncts = puncts ?? new List<Vector2>() { new Vector2(position.X, position.Y) };
if (Vector2.Distance(position, puncts[indexpunkt] = puncts[indexpunkt] ?? new Vector2(position.X, position.Y) ) < 1)
indexpunkt++;
Error:
Error 1 Operator '??' cannot be applied to operands of type 'Microsoft.Xna.Framework.Vector2' and 'Microsoft.Xna.Framework.Vector2'
I wish create new puncts if it is null and add first element to its list.
Can I use operator ?? and how can I use it in if statement?
Vector2 is a Struct and therefore cannot be null, so coalescing operators don't apply.

Resources