Refactor code #108
Replies: 1 comment 2 replies
-
I agree with this proposal that a cleanup is good. Personally i don't mind a breaking change to fix some fundamental things. I think the null and empty check needs to be aligned on all of them. Maybe it is possible to make 1 check for null or empty and return the same message on that check and then if not continue to the real validator? To duplicate every method in the main file is not great for maintainability. I'm trying to think of other ways to keep backwards compat, maybe using How would you imagine a base or abstract class or method? Somthing like this: abstract class BaseValidator<T> {
final String? errorText;
BaseValidator({this.errorText});
String? validate(T? valueCandidate);
String? call(T? valueCandidate) {
if (valueCandidate == null ||
(valueCandidate is String && valueCandidate.trim().isEmpty) ||
(valueCandidate is Iterable && valueCandidate.isEmpty) ||
(valueCandidate is Map && valueCandidate.isEmpty)) {
return errorText ?? FormBuilderLocalizations.current.requiredErrorText;
}
return validate(valueCandidate);
}
} Example: class MaxValidator<T> extends BaseValidator<T> {
final num max;
final bool inclusive;
MaxValidator({required this.max, this.inclusive = true, String? errorText}) : super(errorText: errorText);
@override
String? validate(T? valueCandidate) {
final number = valueCandidate is num
? valueCandidate
: num.tryParse(valueCandidate.toString());
if (number != null && (inclusive ? number > max : number >= max)) {
return errorText ?? FormBuilderLocalizations.current.maxErrorText(max);
}
return null;
}
} Example using type: class MinWordsCountValidator extends BaseValidator<String> {
final int minCount;
final bool allowEmpty;
MinWordsCountValidator({
required this.minCount,
this.allowEmpty = false,
String? errorText,
}) : super(errorText: errorText);
@override
String? validate(String? valueCandidate) {
int valueWordsCount = 0;
if (valueCandidate != null && valueCandidate.trim().isNotEmpty) {
valueWordsCount = valueCandidate.trim().split(RegExp(r'\s+')).length;
}
if (valueWordsCount < minCount && (!allowEmpty || valueWordsCount > 0)) {
return errorText ??
FormBuilderLocalizations.current.minWordsCountErrorText(minCount);
}
return null;
}
} Sample with regex that user can change: /// Default email regex pattern
RegExp _defaultEmailRegex = RegExp(
r"^((([a-z]|\d|[!#\$%&'*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\xD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\xD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\xD7FF\uF900-\xFDCF\uFDF0-\xFFEF])*([a-z]|\d|[\u00A0-\xD7FF\uF900-\xFDCF\uFDF0-\xFFEF])))\.)+(([a-z]|[\u00A0-\xD7FF\uF900-\xFDCF\uFDF0-\xFFEF])|(([a-z]|[\u00A0-\xD7FF\uF900-\xFDCF\uFDF0-\xFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\xD7FF\uF900-\xFDCF\uFDF0-\xFFEF])*([a-z]|[\u00A0-\xD7FF\uF900-\xFDCF\uFDF0-\xFFEF])))$",
);
class EmailValidator extends BaseValidator<String> {
final RegExp emailRegex;
EmailValidator({
String? errorText,
RegExp? emailRegex,
}) : emailRegex = emailRegex ?? _defaultEmailRegex,
super(errorText: errorText);
@override
String? validate(String? valueCandidate) {
return emailRegex.hasMatch(valueCandidate!.toLowerCase())
? null
: errorText ?? FormBuilderLocalizations.current.emailErrorText;
}
} Would it be an idea to let users override the regex or check for a validator? Or maybe implement their own in the user code and add it to the validators using an interface? |
Beta Was this translation helpful? Give feedback.
-
Thanks to all contribution and specially to @martijn00, this package increase the number of validators available to use. This changes, open a new situation to solve that is: How separated the validators?
Currently, we have a form_builder_validators.dart file with all validators and form_field_validator_extensions.dart with some extension methods.
To avoid more than 1000 lines of code on form_builder_validators.dart, I think that need refactor FormBuilderValidators class.
Things that we need to reach:
Proposes:
Beta Was this translation helpful? Give feedback.
All reactions