Dart/Flutter problems with null-safety
In a nutshell: if Dart is certain that a variable at compile time can be null
at runtime, it doesn't compile.. unless you explicitly check for null values, and/or promote the variable to be non-nullable with the !
operator (Dart is not always able to infer the non-nullability in certain situations, so it's our responsibility to promote them to non-nullable).
There's much more to know if you're curious ("why?", for starters), so I'd suggest to check the null safety documentation (quick read).
This being said, your code now changes:
(1) We must check if val
is nullable, before accessing it. We can either use !
or .?
to safely access it; note: the null check operator !
is the least safe null operator, it's likely that it will result in run time exceptions.
validator: (val) {
val==null || val?.isEmpty || val?.length<3
? "Enter Username 3+ characters"
: null
}
(2) I can't infer which method / variable can be null by myself
(3) It depends on what you're trying to do, but I guess that you're trying to implement the Firebase authentication process, in which your user can and should be null before authenticating. Therefore, your function should accept a nullable user value (User?
). In there, we do the usual null
check and we add a !
operator to promote its value in case user
is not null
. As aforementioned, Dart isn't always able to infer nullability of variables.
MyUser _userFromFirebaseUser(User? user) {
return user==null ? null : MyUser(userId: user!.uid);
}
Note how using a null-check !
here is perfectly safe, only because you just checked its nullability in the same line (nonetheless, keep a wise-eye when you refactor this).
EDIT. (4) I can't infer where exactly your exception is fired, but since you want to validate your form, then here's my code from a project of mine:
// inside "saveForm()"...
var currentState = this._formKey.currentState;
if (currentState == null)
return; // this just means something went wrong
if (!currentState.validate()) return; // todo if invalid, handle this, maybe show a snackbar and stuff...
Note how the variable currentState
is now promoted to be non-nullable WITHOUT using the null check operator !
, which is just good practice (avoid using !
whenever possible, PREFER using null-aware operators, such as ?.
or ??
, or ?=
)
Tom Schäfer
Updated on December 31, 2022Comments
-
Tom Schäfer over 1 year
I got the same problem with null statements (?) in Dart multiple times in different cases. I really hope somebody can help me.
Just added some lines of code & the error:
Error:
The property 'isEmpty' can't be unconditionally accessed because the receiver can be 'null'. Try making the access conditional (using '?.') or adding a null check to the target ('!'). here
Here is one of my examples:
child: MaterialButton( onPressed: () { var currentState = this._formKey.currentState; if (currentState == null) { return; } if (_formKey.currentState.validate()) { AuthService.instance.signIn( email: emailTextEditingController.text, password: passwordTextEditingController.text); if (AuthService.instance .checkIfUserExists() == true) { Navigator.pushReplacement( context, MaterialPageRoute( builder: (context) => MainMenu())); } else { Navigator.pushReplacement( context, MaterialPageRoute( builder: (context) => VerifyScreen())); } } },
Got this error-message again:
The method 'validate' can't be unconditionally invoked because the receiver can be 'null'.Try making the call conditional (using '?.') or adding a null check to the target ('!').
After I edited the code with a ! to avoid the Null-Statement like:
singUpUser() { if (formKey.currentState!.validate()) { setState(() { isLoading = true; }); } else { return null; };
But now i just avoid the error in the code itself, after starting a emulator and testing it, next error appears:
Null check operator used on a null value
So thats not the right solution...
If you need more code, just message me.
Thank you!
Tom
-
jamesdlin over 2 yearsHave you read dart.dev/null-safety/understanding-null-safety? For case 1, you need to check that
val
is not null before accessing its members. You didn't say what error your got in case 2; for whatever nullable object you're trying to access, you also need to check for null first (and you might also need to use a null-assertion (!
) operator too). For case 3, you again didn't say what error you got, but theuser != null
check is unnecessary sinceuser
is not nullable, and since the return type isMyUser
and notMyUser?
, returningnull
is not allowed. -
Tom Schäfer over 2 yearsIn the second case I got the same error. Just edited my post above to make my problem bit more detailed. thanks!
-
jamesdlin over 2 yearsFor the second case, as I said, you will need both a null-check and a null assertion.
-
-
Tom Schäfer over 2 yearsThis is some more code from the second example: singUpUser() { if (formKey.currentState.validate()) { setState(() { isLoading = true; }); } }
-
Tom Schäfer over 2 yearsI am really trying to understand the Null-Thing, but for now i just try to avoid it by removing the '!'; thanks for your help! Do you can help me with the code above?
-
venir over 2 yearsHi! Usually what I do in a
Form
widget (inside a_saveForm()
method) is something likevar currentState = this._formKey.currentState;
and thenif (currentState == null) return;
. From now on,currentState
is promoted to be non-nullable, since it is a local variable. Yeah, at the moment this trick just works for local variables. Otherwise, you should do a!
promotion or a?.
null-aware access to it. Please upvote my answer if it was helpful, thank you. -
Tom Schäfer over 2 yearsthanks a lot, but the problem remains; I declared the variable as non-nullable as in your example but after I can't check if the formKey is validate() because of the same error message; edited the code above; thanks for your help!
-
Tom Schäfer over 2 yearsmy goal is to first check if the form recognizes any problems with the text inside the TextFormFields and only if there are no more problems it should start the SignIn() method... does this makes sense in theory?
-
venir over 2 yearsHi, I edited my question - I hope it helps! By the way, it makes total sense to do so.
-
Tom Schäfer over 2 yearsHi, thanks for your example! I understood the Null-Statements two days ago but I couldn't implement it the correct way.. thanks for your help!