google / google/built_value.dart
Separate validation from model building
- Dominant language
- Dart
- Stars
- 886
- Forks
- 195
- Avg merge
- 1d 11h
- Merged PRs (30d)
- 4
Description
## Background
In the generated built value builder, anything not marked with `@nullable` throws an error on `build`.
## Request
I want to be able to separate the validation from the `build` method. Sometimes I want to use built_value for immutability and type safety only, e.g. when editing a model on a form. Validation doesn't make sense in this context because often the user will still be manipulating the form and the form can transiently be in a state where the model has nullable fields. However I need to build the model to emit events to the parent angular component as the user makes changes.
## Example
```dart
class Value {
/// ...
}
class BuiltThing implements Built {
/// ...other bv stuff
/// Not nullable, a valid BuiltThing has a value.
Value get value;
}
@Component(
template:'''''',
directives: [ValueSelectorComponent]
)
class ThingForm {
@Input
BuiltThing thing;
@Output
Stream thingChange => _thingChangeController.stream;
StreamController _thingChangeController = StreamController();
String get value => thing.value;
/// newValue can be null, causing an error
set value(String newValue) => _thingChangeController.add(thing.rebuild((b) => b..value = newValue));
}
```
## Workaround
Sometimes the call to `build` is wrapped in a try catch and the builder is stored as state in the form. This requires more boilerplate.
The other solution is using a model just for the form, which allows nullable for all the fields that can be transiently nullable, and writing converters to translate between the two models. This also requires more boilerplate.
## Solutions
The validation concern may make sense to be moved into a separate package and `@nullable` validation could be entirely removed from built_value.
Or this could be exposed as an optional flag `validate: true` on the annotation.
I would expect additional validations could be added (empty, minLength, min for numbers, etc.), including custom validation for custom types, for example...
`@customValidate((value) => value.startsWith('abc'))`
Contributor guide
Assessment
This issue has not been assessed yet.