I'm using this repository to familiarize myself with Amazon's Cognito user system. In the file lib/screens/signup_screen.dart, starting at line 27 there is this piece of code:
TextFormField(
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(labelText: "Email"),
controller: _emailController,
validator: (value) =>
!validateEmail(value) ? "Email is Invalid" : null,
),
However, since we have null safety in Dart since version 2.x, this piece of code fails with the error message: The argument type 'String?' can't be assigned to the parameter type 'String'
.
What I got from that is that value may not be equal to null and the code cannot guarantee that as it is. Please correct me if I'm wrong and I'm also hoping someone can explain to me why the code cannot guarantee null safety here. If the textfield is empty, value should be equal to ""
instead of null
.
Anyhow, I decided to use the ternary operator to fix this issue:
!validateEmail(value == null ? "" : value) ? ...
Which the IDE suggested I correct to:
!validateEmail(value ?? "") ? ...
Dart also suggested to insert a null check as another alternative:
!validateEmail(value!) ? ....
Up till now, I have just been using these fixes as a workaround to produce code fast without trying to understand what's actually going on.
So what's the difference between these methods? Does the ??
in the second method have an integrated == null
check and is it exactly the same as writing value == null ? "" : value
?
Also, what does the nullcheck value!
do? Yes, it checks if value is equal to null, but what does it do for me when value is in fact equal to null?
The
??
is a null-aware operator , which returns the expression on its left unless that expression’s value is null, in which case it evaluates and returns the expression on its right:Which is the same as doing a ternary operator but more readable.
The bang operator
!
casts aways the nullability of the variable, meaning YOU explicitly say that the value CAN'T benull
.For further reading check out the documentation.