Form validation.
Hi, it would be nice to have an example on how we can do form validation and map errors from the server to a specific field.
Hi @petrubocsanean Okay, I'll keep that in mind. The way I do it is quite simple, store the validation message to show for the field. more dynamic solutions do exist, I've built a dynamic one myself but it doesn't have much to do with stacked.
With that said I have implemented it a few ways based on the requirements so I have some things to share there as well. will sdd it to my list.
form validation example would be great
@yuechaor after i over the new dialog service and navigation service I'll tackle form validation. I've done it a few ways so I'll share 2-3 of them depending on how long the video goes.
@FilledStacks you are amazing, thank you so much
I created my own Stacked-y "ValidationService" that I inject anywhere I need to handle validation tasks in my view models - part of the reason I agree with @FilledStacks that this shouldn't be a packaged service is because I use an additional layer of abstraction over traditional Stacked_Services. I make my services as an [abstract class SomeService] which exposes all of the methods within it, and then an Implementation of that abstract class, which allows interchanging of validation packages for various validation types, and remains unit testable and the consumption of the service never changes beyond that.
For example - notice how I use two different validation packages for Email vs Phone, but the downstream consumers of the abstract methods would never know that, even if I changed the implementation details in ValidationServiceImpl:
abstract class ValidationService {
bool phoneIsValid(String phone);
bool emailIsValid(String email);
bool urlIsValid(String url);
}
class ValidationServiceImpl implements ValidationService {
/// Returns [true] if the phone-number passes valdiation, else [false].
@override
bool phoneIsValid(String phone) {
return Fzregex.hasMatch(phone, FzPattern.phone);
}
/// Returns [true] if the email passes valdiation, else [false].
@override
bool emailIsValid(String email) {
return email.isNotEmpty && EmailValidator.validate(email);
}
/// Returns [true] if the url passes valdiation, else [false].
@override
bool urlIsValid(String url) {
return Fzregex.hasMatch(url, FzPattern.url);
}
//! Constructor
ValidationServiceImpl();
}
@JayPerfetto Thank you for sharing that. That's exactly what I was eluding to. I do the same thing. Different validation packages for different reasons and sometimes different validation implementations in terms of when the validation message is shown. Sometimes it's showng as typing, or 1 second after we stop typing or only when submitted. It's quite a lot to implement for a shared package but I'll share some of the methods I use in a video just to give some guidance to those that are lost.
Your implementation is dope! Thanks again for sharing.
thanks dane! As a follow up - if anyone needs to know how to register this pattern with GetIt ->
locator.registerLazySingleton<ValidationService>(
() => ValidationServiceImpl(),
);
This abstraction technique I got from ResoCoder's great tutorial on Clean Architecture (obviously you can tell which architecture I ultimately chose lol...)
https://resocoder.com/2019/08/27/flutter-tdd-clean-architecture-course-1-explanation-project-structure/#Next_up8230
@JayPerfetto 😄 That is a great series of his. I also show the registration technique in my abstraction video posted a few months back.