ValueContainer is a package that will help you to separate values and validate each value on its own


Use ValueContainer class on its own

This validator will always return Value must be true error message if value is not true

final container = ValueContainer<bool, String>(
    name: 'AlwaysTrue',
    value: false,
    validator: (value) => value == true ? null : 'Value must be true',



AlwaysTrue(value: false, isValid: false, error: Value must be true)

Extend ValueContainer

You can create your own value container too

class EmailAddress extends ValueContainer<String, String> {
  EmailAddress([String? email])
      : super(
          name: 'EmailAddress',
          value: email,
          validator: validator,

  static String? validator(String? value) {
    if (value == null || value.isEmpty) return 'Email address is required';

    if (!value.contains('@')) return 'Email address must contain @';

    return null;

now lets create an invalid instance of it

  final emailAddress = EmailAddress('my_email_address');


EmailAddress(value: my_email_address, isValid: false, error: Email address must contain @)

now lets crate a valid instance of it

  final emailAddress = EmailAddress('');


EmailAddress(value:, isValid: true, error: null)

Typed Errors ValueContainer

Lets define an Abstract Class called PasswordError and use it as error type

class PasswordError {
  final String message;

  const PasswordError(this.message);

  toString() => 'PasswordError($message)';

Lets create our error classes

class RequiredPasswordError extends PasswordError {
  const RequiredPasswordError() : super('Password is required');

class MinimumLengthPasswordError extends PasswordError {
  const MinimumLengthPasswordError({int length = 6})
      : super('Password must be at least $length characters');

lets create our custom ValueContainer

class Password extends ValueContainer<String, PasswordError> {
  Password([String? password])
      : super(
          name: 'Password',
          value: password,
          validator: validator,

  static PasswordError? validator(String? value) {
    if (value == null || value.isEmpty) return RequiredPasswordError();

    if (value.length < 8) return MinimumLengthPasswordError(length: 8);

    return null;

Now lets use our custom value container

final pass = Password();

  final pass2 = Password('123456');

  final pass3 = Password('12345678');

  if (pass.hasErrorOf<RequiredPasswordError>()) {
    print('Pass: Password is required');
  // or //
  pass2.onErrorOf<MinimumLengthPasswordError>((password, error) {
    print('pass2: Password is too short');


Password(value: null, isValid: false, error: PasswordError(Password is required))
Password(value: 123456, isValid: false, error: PasswordError(Password must be at least 8 characters))
Password(value: 12345678, isValid: true, error: null)

Pass: Password is required
pass2: Password is too short