Evyatar Alush - Up your form validation game with Vest

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] [Music] [Music] as users of the web we often come across forms that are so hard to use that it almost feels intentional for example when you type in one character in one input field and suddenly all the other fields light up as well as if they have a validation error inside or when it doesn't matter how much you try you just can't seem to be able to submit the form and i have just one question for you the forms on the web have to suck hi everyone i'm aviatar i'm a front-end engineer at meta and i'm the author of vast validations framework if you want to check out the stuff i do you can go to my home page or get a profile and i'm also on twitter today i want to talk to you about how you can use the vest to improve the way you write form validation in your valved apps and vest is an open source form validations framework it's framework agnostics so you can use it with any ui framework out there and it's highly inspired by unit testing libraries like mocha or chest so if you've used either you'll feel very much at home working with best but before i talk about vest itself i first want to mention some of the problems i was facing that led me to write best to begin with and i think there are three main problems first when writing for validation there's a big lack of structure we're never sure where to put the validation code there is no coherent structure the validation should be written in especially if we have multiple validations that some of them are feature specific some of them are not if we have um fields that depend on one another and eventually we do make it work but everything becomes very feature specific type back and down to the feature itself and it is very hard to separate and when you come back to maintain the form like months later to add more fields that you didn't plan on or change the logic in a way that you didn't think you would need to do in in the future you sometimes have to actually refactor the feature itself just to accommodate for this tiny validation change and because forms are the interaction heavy parts of our apps they are also very hard to test because everything we try to do for example if we want to test fields that depend on one another or some conflict between fields we first have to simulate the user events and these are very costly so we end up not doing this and unfortunately forms are the interaction heavy parts of our apps so this is usually where our users face bugs and i our users deserve more i think and a couple years ago i thought about fixing this and i thought what would the ideal solution be and the ideal solution has to accommodate for all of these first it has to be separate from the feature code so it cannot be feature specific and it shouldn't require a feature effector just to make a change second it has to be very easy to read very easy to write and very easy to understand and back in the day i was learning first about for a unit test with mocha and later with chest and the similarity struck me because what we do in unit tests is essentially what we want to do with form validation we have our functions that we run through a series of tests to make sure they behave correctly and this is separate from the feature and when we work with form validation this is exactly what we want to do to our data we have our data that comes from the inputs and we run we want to run it through a series of tests just to make sure the data is written correctly and i tried to use this same pattern for form validation and i came up with something very nice i think first we have our form validation suite that we create and inside of it we have the sweep body the suite body has the different tests and these are very similar to unit test tests only that you specify the field name that you're validating the message that the user would get in case of an error and then the validation body the test body and it looks like this we have our enforce which is very similar to just expect or search and you enforce that some value matches some criteria and apparently this works perfectly for form validation and i want to show it to you in action what we have here is a very basic spell form it is not connected to best yet and we're going to do it now so i'll show you the form we have two input components and one submit button and the input component is very basic it has an on input um change handler that all it does is just passes the name of the field that we're interacting with and we have a few more props to the input so we have dependent prop that shows the spinner in case of an async validation we have a validity class that gives a class name of either error success or warning to the form or to the input and also we have a messages array that takes an array of strings and when added it shows a validation message to the user this is all we have at the moment let's try trying our form validation so first i'll import in a new file create from best and i'll create my new suite so const suite equals create and it takes a call back and let's initialize it with an empty data object and now this will be the data that we get from the form now let's export default suite and also let's write the first test so this will be for username so let's important force and test and now let's do test that username let's say a username is required this will be the message the user would get in case of a validation failure now let's do enforce a data dot username is not blank now this does not do anything yet because we're not connecting it to this valve yet but it should be very easy so first let's import our suite so import suite from sweet and let's get the validation result from the suite so in a new variable let's do let um res which will be our validation result equals sweet dots get this has the most up-to-date validation result and also let's connect it to the form to the input so let's do messages equals res.get errors or the filled username now all we have to do is just unchange run the validation so let's do inside of it let's do res equals suite and pass it our form state all our inputs so form state now if i type inside username and remove it we'll see username is required just like that now that was easy but this is a very simple validation let's make it more complex so let's add a few more inputs or a few more uh tests we can add another test for username for example we can have multiple fields for the same validation for the same field but not in the same function which is very easy to read and you can see what is failing very clearly so let's do instead username must be at least three characters and let's do um longer than and let's say two now let's duplicate this for password as well and let's say a password must be at least five characters because it should be um stronger so let's do longer than or equals perfect now let's connect the password field to it as well and if i type inside username we see the validation for username and we see the validation for password but you saw this as well right um when i just typed inside username we got a validation message for password which is okay when we hit submit it's okay when we write the validation for the server but this is not good for regular user interaction and fortunately this is very easy to handle um this allows us to specify which fields we want to validate and this is really easy so in our change handler we have the name of the field that we're validating let's pass this data to the suite as well and let's also accept it here so field name let's say field name and now i'll take the only function from vest and only allows us to specify which field we want to validate and here let's do only fill name and now if i start typing inside the username field only the username field is validated and if i type inside password only the password field is validated now i promised you callers um with the error messages the error class name and everything so let's do it vest is not a ui framework but it does come with some ui helpful utilities like class names and what class names does is it allows us to specify a valid validation class name to show it any validation state let's see oh class names to show a validation class name at any validation state so what we do here is we can specify a few class names to show at any stage so for example let's do a cn cn is what it gives us back um class names gives us back a function and it takes the validation result now let's do let's do when it's valid will show success when it's invalid will show error and when it's warning let's show warning now all we have to do is pass it over to the validity class so for example in our input component for username let's do validity class and say cm for username and let's do the same for password and now if i type inside username it's getting green so i must have an a valid oh invalid i have a typo here okay so it becomes red and if i type inside password it's red as well and then it's green now while we're here let's also disable the submit button on validation failures so only when it's valid it should be enabled so let's also do um disabled equals red not res is valid now i can take this and add it to the submit button and now i can refresh and we'll see that the submit oh this a bold yep tackles um we see that it's disabled and now if i start typing we'll see that it works correctly now what if i had a validation that shouldn't prevent submission so for example i have the password strength validation that even if the password is weak we want to allow the user um to submit their form this might be very difficult to do with other frameworks with best it's really simple all we have to do is import worn from best and create a warning test so what it does is specifies that this test is put in a different basket let's do for example a simple test for a warning let's do maybe add a number because it's optional and let's put inside worn now instead of longer than or equals let's do matches and put a regular expression um for has a number inside now if we start typing inside password and pass the five characters we see that it's orange we're still not seeing the validation message which makes sense we only asked for the validation warnings so let's go over there and let's do um as we said they get errors returns us an array so let's do concat res dot get warnings for password now if i start typing oh you already see it if i start typing you see that maybe add a number now this is nice this is very simple to do but what if we had a more complex validation for example an async validation for um user already taken this could be again very difficult to do with a different framework with best it could be very simple and all we have to do is return a promise or an async function from our test so first i'll use my api function my mock api import does user exist from api this is a function that returns as uh that rejects a promise in case of a user that already exists and i can tell you that my username is in the is on the list of taken user names and what i have to do here is test that username and let's say user already taken and now i'll pass in the function does user exist and passover mydata.username now will not see anything if i start typing because we did not show the spinner in case of a validation for the username field so let's do this inside our change handler let's say if name equals a username let's do username pending equals true now we also have to cancel it when the validation is complete and all we have to do now is res dot done which gives us back a callback when the validation is complete let's do um result this gives us back the result let's say res equals result the most up-to-date result with the async validation result and also let's do user name handing defaults now if i type inside username we see the spinner and it disappears after a second and if i type my username we'll see after a second the users are already taken and if i add another character it's not taken anymore now let's say that everything else still works so example one yep everything still works now if i remove everything you'll see a spinner here even though the validation um is already failing for the user so it's too short or it's empty and we shouldn't go to the server to make a costly validation when we already know that the field is failing and we can tell that hey hey hey please don't don't do this don't validate when the username field is is invalid to begin with and this is using the skip when uh conditional this allows us to wrap some field in a conditional and say i don't validate when this condition is truthy and all we have to do is sweet dot get and this gives us the most up to date in our case the intermediate validation result has errors for username so as long as we have errors for username the async validation won't run it will be registered but it won't run so let's do as we can see there's no spinner now and if i type my full username it is shown and i'll type another character and now remove it and we see that even though we know that a user is already taken because we ran it before we still go out to the server again and what we would usually do is memoize the validation result and tell best hey we already have it so we don't have to go outside but thus does it for us all we have to do is add test.memo and then tell best hey we have here a dependency array and as long as the values inside this array don't change so for example data dot username as long as the valid the values in this array don't change just don't go outside just use what you have and what we do here is type my username and we're going to see the spinner add another character with the spinner again and what i expect to happen here is when i move that number i edit at the end we should not see the spinner but instead we should see the validation result immediately and if i remove one character this is exactly what happened we see the validation result immediately and again if i add a character um instead of going after the server and as you can see let's check that everything works uh yep everything works perfectly as you can see we were able to introduce vest into our form with only a few lines of logic if you call that logic inside your code it's very easy to use it's very readable um and easily to me and easy to maintain because you see everything it does right here and you don't have to refactor a picture to make changes now we've seen some of this feature he features it has more features and more than you can see here um we can validate that the changed field upon interaction we can validate multiple tests for the same field we have warning validations that don't fail the validation we can make fields that depend on one another we have async validations and we can memoize them we can group them inside best baskets and in in general the form and the and the validations are structured so they are really easy to move around change modify um read and write now going back to my question from before no forms on the web don't have to suck they can pretty easily become pretty good and i think best brings to the table both power and comfort now vast community is still growing so if you are interested in helping out with the project feel free to go to the github page or reach me on twitter and if you're just interested in using investing or smelt app you can go ahead to the documentation page you'll find there this exact example using smelt and other frameworks as well so reach out enjoy thank you so much for joining me today it was a pleasure bye
Info
Channel: Svelte Society
Views: 1,585
Rating: undefined out of 5
Keywords: Svelte, Javascript, Web development
Id: X2PuiawaGV4
Channel Id: undefined
Length: 19min 51sec (1191 seconds)
Published: Sat Nov 27 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.