0

I am getting argument type not assignable error in dart while checking the email value is empty or not the error which I am getting are

The argument type void Function(String) can't be assigned to the parameter type void Function(String?)?.

and

The argument type String? Function(String) can't be assigned to the parameter type 'String? Function(String?)?.

These are the validator classes,

class EmailFieldValidator {
static String? validate(String value) {
    return value.isEmpty ? 'Email can\'t be empty' : null;
  }

}

class PasswordFieldValidator {
  static String? validate(String value) {
    return value.isEmpty ? 'Password can\'t be empty' : null;
  }
}

Here is the code giving the error

 List<Widget> buildInputs() {
    return <Widget>[
      TextFormField(
        key: Key('email'),
        decoration: InputDecoration(labelText: 'Email'),
        validator: EmailFieldValidator.validate, //this gives string error mentioned above
        onSaved: (String value) => _email = value, //getting void error mention above 
      ),
      TextFormField(
        key: Key('password'),
        decoration: InputDecoration(labelText: 'Password'),
        obscureText: true,
        validator: PasswordFieldValidator.validate,  // getting string error mentioned above
        onSaved: (String value) => _password = value, //getting void error mention above 
      ),
    ];
  }
Mithson
  • 1,554
  • 13
  • 33
  • What do you understand of those error messages? – Alexander Aug 28 '21 at 16:10
  • I guess the error message says that it isnt allowing to assign a non-nullable value to nullable type and I tried to make suitable changes but that didnt worked out like adding null check(!) – Mithson Aug 28 '21 at 16:18
  • 1
    The null check isn't the issue. It's the types of the `XFieldValidator.validate` functions themselves. Nothing you do within those functions is relevant to the error, the issue is that their types are incorrect. As the error suggests, the type expected by `TextFormField` for its validator is `String? Function(String?)`, so you need to declare it with a function signature of `String? validate(String? value)`. – Alexander Aug 28 '21 at 16:43
  • thanks a ton @Alexander, I gotcha and solved the error for both – Mithson Aug 28 '21 at 16:51
  • I've formalized my comment into a more fleshed-out answer. Hopefully I've helped you built some understanding on what these errors mean, and the fix from there should be straight forward. Let me know if you have any questions. – Alexander Aug 29 '21 at 02:56

3 Answers3

1

This is a problem faced after the Null Safety thing came to flutter. I just normally cast it as a String to use it. Sometimes it gives out errors but not errors which will potentially break your app.

onSaved: (String? value) => _email = value as String,


static String? validate(String? value) {
String valueString = value as String;
// Do Your Usual thing over here like checking if it's empty}
  • thanks @kushalagrwal Alexander just explained me what silly error I made Thanks for your contribution – Mithson Aug 28 '21 at 17:09
  • This force cast completely defeats the purpose of null safety. – Alexander Aug 28 '21 at 17:32
  • @Alexander so is it better to use null safe var or force casting? – Mithson Aug 28 '21 at 17:48
  • Yes I know therefore I did mention that it's just a temporary fix. And therefore it gives out errors too at points. But yes good point. – Kushal agrawal Aug 28 '21 at 19:07
  • @Mithson Well let me ask you this: why do you think the Flutter API was designed such that `onSaved` takes a function with an optional `String` parameter. Why didn't they just accept a function with a non-optional `String` parameter? – Alexander Aug 29 '21 at 02:46
1

First error

Both EmailFieldValidator.validate and PasswordFieldValidator.validate have the same type: String? Function(String). That is to say, they're both functions that take a non-optional String as a parameter, and return a optional String.

The error message is telling you that the validator parameter to TextFormField is expecting a function with the type String? Function(String?)?. That is to say, a optional function (that is, you can pass null if you don't need any validator functionality at all), which itself accepts a optional String parameter, and returns a optional String.

Notice the difference: The parameters of your validator functions are not optional, but they're required to be optional. Thus, you'll need to change their function signatures:

static String? validate(String? /* ⬅️ Notice this is now optional! */ value) { ... }

Though one might ask: why not just use a lambda here, and have the types be inferred?

Second error

The error is similar. Looking at the docs of TextFormField's constructor, we see that the type of the onSaved parameter is FormFieldSetter<String>, where FormFieldSetter is just a typealias for void Function(T? newValue). Thus, the resolved type of the onSaved parameter is void Function(String? newValue).

The lambda function you passed, (String value) => _password = value, takes a non-optional String parameter. Notice the mismatch. It needs to accept an optional, because the saving process might yield a null value, and you'll need to handle that.

How exactly you handle that null is up to you, and depends on your requirements. You might want to end up saving the null in your database (for example) if the field isn't mandatory. Or you might substitute a default value (though that doesn't make sense in this context). Or you in the extreme case, if you're absolutely sure you'll never ever get a null, you could force unwrap it. Of course, doing is as if you're saying the following to Dart:

I'm super-duper sure this will never be null. If it is, the sky is falling, and I haven't devised a way to deal with that yet. Things are clearly not working the way I expected. Rather than carrying on forward in this misbehaved state, please just crash my app and prevent further damage

Whether that's desirable or not, depends on your problem domain.

Alexander
  • 59,041
  • 12
  • 98
  • 151
0

The problem that you might return a null value whil it does not let you to use null there.

Try to add ! after value:

onSaved: (String value) => _email = value!, 
onSaved: (String value) => _password = value!, 
stacktrace2234
  • 1,172
  • 1
  • 12
  • 22
  • I tried adding null check but it throws ```The '!' will have no effect because the receiver can't be null. Try removing the '!' operator.``` – Mithson Aug 28 '21 at 16:26