
FPFormz
Functional input validation library based on Fpdart,
which is inspired by Formz.
Features
For the most part, FPFormz is similar to the original Formz library, with a few notable differences:
-
FPFormz allows specifying different types for input and validated values, which can be convenient
when using non-string type values (e.g.int
,enum
, value class, etc.). -
It exposes validated values and errors as functional constructs such as
Either
orOption
,
making it easier to manipulate them declaratively. -
It also provides a way to write validation logic as mixins, which you can combine to handle more
complex use cases.
Installation
You can install PFFormz by adding the following entry in your pubsec.yaml
:
# pubspec.yaml
dependencies:
fpformz: ^0.1.0
Getting Started
FormInput And Its Derivatives
To define a validatable input, you need to write a class that extends FormInput<V, I, E>
whose
generic parameters correspond to the type of resulting value, input value, and potential errors,
respectively:
After declaring your input, you can use either pristine
or dirty
constructor to create an
instance:
void example() {
// To create an unmodified ('pristine') input instance:
final age = AgeInput.pristine('age', '');
// Or you can create a modified ('dirty') input instance as below:
final editedAge = AgeInput.dirty('age', '23');
print(age.isPristine); // returns 'true'
print(editedAge.isPristine); // returns 'false'
}
You can access validation information either as a functional construct, or as a nullable:
void example() {
print(editedAge.isValid); // returns true
print(editedAge.result); // returns Right(23)
print(editedAge.resultOrNull); // returns 23
print(editedAge.error); // returns None
print(editedAge.errorOrNull); // returns null
print(age.isValid); // returns false
print(age.result); // returns Left(ValidationError)
print(age.resultOrNull); // returns null
print(age.error); // returns Some(ValidationError)
print(age.errorOrNull); // returns ValidationError
}
And because most input components treat the user input as a String
instance, you can simplify the
type signature by extending from StringFormInput
:
Form
Like with Formz, you can create a form class to host multiple input fields and validate them
together:
Then you can validate it using a similar API like that of FormInput
:
void example() {
final form = RegistrationForm();
print(form.isPristine); // returns true
print(form.isValid); // returns false
print(form.result); // it 'short circuits' at the first error encountered
print(form.errors); // but you can get all errors this way.
}
Mixins
You can also write reusable validation logic as a mixin:
And build a concrete input field by adding them to either BaseFormInput
or StringFormInput
as
shown below:
It’s recommended to split each validation logic into a separate mixin rather than putting all into
an input class to maximise code reuse and achieve separation of concerns (i.e. the ‘S’
in SOLID principles).
FPFormz also ships with a small collection of ready-to-use mixins like NonEmptyString
, StringShorterThan
, which might be expanded in future versions.
Additional Information
You can find more code examples in our test cases.