VeryGoodOpenSource / formz

A unified form representation in Dart used at Very Good Ventures 🦄

Home Page:https://pub.dev/packages/formz

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Issue error text from Formz

christnick opened this issue · comments

Keep in mind I'm pretty new to development so perhaps there is an obvious solution I'm missing.

I would like to have an option for different error messages. For example maybe a description field could give an error message that says "this field can't be blank" and another that says something about the length of the input if it is too long.

enum DescriptionValidationError { empty, tooLong }

class Description extends FormzInput<String, DescriptionValidationError> {
  const Description.pure() : super.pure('');
  const Description.dirty([String value = '']) : super.dirty(value);

  @override
  DescriptionValidationError validator(String value) {
    if (value.isEmpty) {
      return DescriptionValidationError.empty;
    } else if (value.length > 10) {
      return DescriptionValidationError.tooLong;
    } else {
      return null;
    }
  }
}

Is there a way in my textfield widget to say
errorText: state.description.errorText

I can do this in my widget but I'm not sure its really best to have that logic in the widget - it feels like it should be in the class that extends formz?

return BlocBuilder<InputCubit, InputState>(
      buildWhen: (previous, current) =>
          previous.description != current.description,
      builder: (context, state) {
        String errorText;
        switch (state.description.error) {
          case DescriptionValidationError.empty:
            errorText = 'This cant be empty';
            break;
          case DescriptionValidationError.tooLong:
            errorText = 'Its too long';
            break;
          default:
            errorText = null;
            break;
        }
        return FormTextInput(
          formKey: Key('recipeInput_descriptionField_textField'),
          onChanged: (title) =>
              context.read<InputCubit>().descriptionInputChanged(title),
          labelText: 'Description',
          errorText: state.description.invalid ? errorText : null,
          maxLength: 160,
        );
      },
    );

Best,
Nick

Hey @christnick great question!

Personally, I think separating the state from the error message itself is a good thing: state is part of the business logic, while the error message is part of the UI.

One thing you could, however, is to use a Dart extension (https://dart.dev/guides/language/extension-methods) to make this code a bit "prettier".

For example (in some pseudo code form):

extension ErrorMessage on DescriptionValidationError {
  /// Passing context in case you need to localize
  String? errorMessage(BuildContext context) {
        switch (this) {
          case DescriptionValidationError.empty:
            errorText = 'This cant be empty';
            break;
          case DescriptionValidationError.tooLong:
            errorText = 'Its too long';
            break;
          default:
            errorText = null;
            break;
        }
  }
}

...

return FormTextInput(
          formKey: Key('recipeInput_descriptionField_textField'),
          onChanged: (title) =>
              context.read<InputCubit>().descriptionInputChanged(title),
          labelText: 'Description',
          errorText: state.description.invalid ? state.description.errorMessage(context) : null,
          maxLength: 160,
        );

Hope that helps ;)

Hrmm... you could be right there. Either way I learnt about extension methods and implemented your pseudo code for now and its working nicely.

Learning to code here and I'm constantly taken aback by how helpful people can be. Thanks very much for your help :)