2

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

3
  • Have 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 the user != null check is unnecessary since user is not nullable, and since the return type is MyUser and not MyUser?, returning null is not allowed. Commented Aug 3, 2021 at 20:51
  • In the second case I got the same error. Just edited my post above to make my problem bit more detailed. thanks! Commented Aug 5, 2021 at 7:48
  • For the second case, as I said, you will need both a null-check and a null assertion. Commented Aug 5, 2021 at 8:12

2 Answers 2

2

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 ?=)

Sign up to request clarification or add additional context in comments.

7 Comments

This is some more code from the second example: singUpUser() { if (formKey.currentState.validate()) { setState(() { isLoading = true; }); } }
I 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?
Hi! Usually what I do in a Form widget (inside a _saveForm() method) is something like var currentState = this._formKey.currentState; and then if (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.
thanks 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!
Hi, 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!
|
0

Being empty is not the same as being null. So before you can check an object is empty, you need to check against null first.

if (obj != null && !obj.isEmpty) {} 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.