Manually setting Flutter Validation Error

9,692

Solution 1

It's actually super simple and the validation error still works aswell.

String? _errorMsg;

Widget build(BuildContext context) {
...
  TextFormField(
    onFieldSubmitted: (value) => _signIn(),
    validator: (input) {
      if (input.length < 6)
        // will set the errorText directly, no need for a variable here
        return 'Your password is too short';
      return null;
    },
    onSaved: (input) => _password = input,
    decoration: InputDecoration(
      labelText: 'Password',
      errorText: _errorMsg,
    ),
    obscureText: true,
  )
...
}

Future<void> _signIn() async {
  setState(() {
    _errorMsg = null; // clear any existing errors
  });

  final formState = _formKey.currentState;
  if (!formState.validate()) return;
  formState.save();

  try {
    ... // do fancy request stuff
  } catch (e) {
    setState(() {
      _errorMsg = 'Wrong password.';
    });
  }
}

Solution 2

You can use controller in TextFormField to validate form and display server error.

TextEditingController controllerPassword = new TextEditingController();
Widget build(BuildContext context) {
...
  TextFormField(
    onFieldSubmitted: (value) => _signIn(),
    validator: (input) {
      if (input.length < 6)
        return 'Your password is too short';
      return null;
    },
    onSaved: (input) => _password = input,
    decoration: InputDecoration(
      labelText: 'Password',
    ),
    obscureText: true,
    controller: controllerPassword,
  )
...
}

Future<void> _signIn() async {
  final formState = _formKey.currentState;
  if (!formState.validate()) return;
  formState.save();

  try {
    ... // do fancy request stuff
  } catch (e) {
    // this is where I want to set the "validation" error
     setState(() {
        controllerPassword.text = "Server Error"
     }));
  }
}

For more reference: Flutter Form Validation

Solution 3

I suppose, I could think of a solution, but I think it's kind of ugly. I could have an "error" variable, that is set when the request fails. I would then call formState.validate() a second time, in there: check the error variable and return it if it's not null.

Share:
9,692
EzPizza
Author by

EzPizza

Updated on December 14, 2022

Comments

  • EzPizza
    EzPizza over 1 year

    After validating a form and sending a request from flutter to the server backend: I want to set any potential error message from the server to be displayed in the original form. Preferably exactly like a validation error.

    For instance:

    Widget build(BuildContext context) {
    ...
      TextFormField(
        onFieldSubmitted: (value) => _signIn(),
        validator: (input) {
          if (input.length < 6)
            return 'Your password is too short';
          return null;
        },
        onSaved: (input) => _password = input,
        decoration: InputDecoration(
          labelText: 'Password',
        ),
        obscureText: true,
      )
    ...
    }
    
    Future<void> _signIn() async {
      final formState = _formKey.currentState;
      if (!formState.validate()) return;
      formState.save();
    
      try {
        ... // do fancy request stuff
      } catch (e) {
        // this is where I want to set the "validation" error
      }
    }