Displaying Validation Errors and Validating from our Request
In this lesson, we'll learn how we can display feedback for invalid fields noted by errors from our VineJS validators. We'll also see how we can validate directly from our request using request data.
- Author
- Tom Gobich
- Published
- Apr 09
- Duration
- 7m 16s
Developer, dog lover, and burrito eater. Currently teaching AdonisJS, a fully featured NodeJS framework, and running Adocasts where I post new lessons weekly. Professionally, I work with JavaScript, .Net C#, and SQL Server.
Adocasts
Burlington, KY
Transcript
Displaying Validation Errors and Validating from our Request
-
(upbeat music)
-
So when we submitted our form and got our error back,
-
what actually happened there?
-
Well, as expected,
-
Vine.js and AdonisJS communicate with one another.
-
When Vine.js receives a validation error,
-
it's going to report that to AdonisJS.
-
And AdonisJS is going to validate that error
-
into an HTTP response automatically
-
based on the accept header value using content negotiation.
-
Meaning, if you were to submit your request
-
with an application JSON accept header,
-
you'll get back a JSON based response.
-
If you submit it with an application NVD API plus JSON header,
-
you'll get back a response formatted specifically
-
for the JSON API spec.
-
And then if you submit a server rendered form,
-
as we have in our last lesson,
-
it will use the session package to submit back
-
a flash message summary of our errors.
-
If none of the above is true,
-
it will just submit back in plain text.
-
So following this logic,
-
our errors were submitted back to us
-
via the session package as flash message errors.
-
So if we dive back into our application,
-
hide that back away and jump back into our register page,
-
let's inspect exactly what we're getting.
-
So before all of our fields,
-
let's do double curly braces, inspect.
-
And there's a global property called flash messages
-
that contains all flash messages.
-
And it also has some properties
-
that help us work directly with our flash messages as well.
-
Things like has to check whether or not
-
flash messages has a particular value
-
to get a particular flash message
-
and also all so that we can get all flash messages.
-
So let's inspect the all response
-
whenever we submit our form with invalid data.
-
At present, you can see it's just an empty object
-
because it has nothing inside of it.
-
For our full name, we'll continue along our same path.
-
Our email, we'll use our [email protected]
-
that already exists inside of our database
-
and we'll type in some password.
-
Actually, let's take our password
-
underneath eight characters so that fails as well.
-
So we would expect our email to fail
-
with our uniqueness check
-
because we're submitting a non-unique email
-
and we're also expecting our password to fail
-
the min length requirement
-
that we've added of eight characters.
-
So whenever we hit register here,
-
we're redirected back and we can see
-
that our flash messages contains a few things for us.
-
We have our full name and email that we've submitted.
-
Password has been omitted here for security sake.
-
And then we have our input error bag,
-
which contains errors specifically
-
for our HTML input fields.
-
Then we have generalized errors down here as well.
-
These also contain our input errors,
-
but our input errors is specifically
-
just for the input errors,
-
whereas errors is for general errors as a whole.
-
Within both of these errors,
-
we see that our email has failed
-
because the email has already been taken
-
and the password has failed
-
because the password field
-
must have at least eight characters.
-
So what's returned back to us
-
are the actual validation error messages
-
that we can then display back to the user directly.
-
So if we hide our browser back away,
-
get rid of our inspect call
-
and let's start with just our email here at first.
-
So there's a global flash messages property
-
made available by AdonisJS via the session package.
-
So we can do @if flash messages
-
and inside of our has method,
-
all that we wanna do is specify the identifier
-
specifically for our error.
-
So for this, we can reach inside of our errors object
-
and then we can use a dot based syntax
-
to specify that we wanna reach inside of that errors object
-
and check specifically for the email key
-
inside of that object.
-
So if our flash messages has an errors.email value,
-
then we'll end our if and we'll want to display that error.
-
So we can use double curly braces,
-
reach for our flash messages and then get that error.
-
So errors.email.
-
And as we just saw, this will return back as an array.
-
So lastly, we can join that
-
as a comma delimited list of errors.
-
Okay, we'll give that a save.
-
Let's jump back into our browser
-
and try submitting once more.
-
So john [email protected]
-
because that already exists inside of our database,
-
we wanna test our failures
-
and we haven't quite added our error yet for our password,
-
but we'll enter whatever in for there.
-
Okay, let's run this and there we go.
-
So now we can see that our email has already been taken.
-
Perfect, so we're getting our validation error.
-
Since find, Adonis and edge all work together in synchrocy,
-
we can actually use a utility to make this call
-
a little bit easier as well.
-
So let's hide our browser back away
-
and instead of doing all of this boilerplate work,
-
we can instead use some helpers.
-
So there's an input error helper tag.
-
It's going to use that input errors bag
-
that we saw whenever we inspected our flash messages
-
to determine whether or not we have an error available.
-
So this is going to work similar to an if check.
-
So we can jump down here and end that tag.
-
Inside of this method,
-
we want to provide back just the input name
-
that we want to check against, which would be our email.
-
And then this input error,
-
if it determines that we have an error
-
to display for our email,
-
we'll inject that errors array
-
directly inside of this tag as dollar sign messages.
-
So if we want to display all messages,
-
we could loop over them
-
or we could just join them together
-
as a common delimited list.
-
And so now we can use this rather than all of this
-
to display our error messages.
-
Furthermore, we can just copy this,
-
paste it down on our password,
-
update the field name to password
-
to match the name of the actual field
-
that we're using or the input.
-
And then let's do the same thing here for our full name.
-
So full name there.
-
Awesome.
-
So now we have input error handlers
-
added in for all of our registration inputs.
-
So if we dive back into our browser,
-
let's type this out once more.
-
and some not quite a character value for our password.
-
Hit enter, and there we go.
-
So now we get the email has already been taken still
-
for our email and the password field
-
must have at least eight characters for our password.
-
We can style that up a little bit as well
-
by providing whatever we want inside of this input error.
-
So we could do, let's say a paragraph with class text,
-
extra small text, red 500,
-
and plop the value inside of there.
-
And since all of these use that same messages,
-
dollar sign join,
-
we could just give this whole thing a copy
-
and paste that into each one of our errors.
-
And if you're thinking ahead,
-
you can probably already start to guess
-
how we can compose this label, span, input,
-
and error all into a component.
-
But if you're not quite there,
-
we'll take a look at that here in a little bit.
-
Okay, so let's jump back into our browser.
-
Give this one more test.
-
and some password, not quite eight characters.
-
Hit enter, and there we go.
-
So now the text is smaller and it's red.
-
Before we move onward though,
-
we can actually simplify our validation logic as a whole
-
inside of a register controller as well.
-
So currently we're using the actual validation schema
-
to perform our validation
-
and providing in that data manually.
-
Well, since AdonisJS and Find.js work great together,
-
Find.js is actually available directly on a request
-
and it will be able to automatically pluck
-
our request data out for us.
-
And then all that we need to do is specify the schema
-
that we want to validate with.
-
Kind of just inversing the flow
-
of what we have going on here.
-
So let's do that up here at the top.
-
So you can do const data.
-
We'll ignore that red squiggly here
-
since we've already defined data.
-
And we can await request.validateUsing.
-
And then all that we need to do
-
is provide it the validator that we want to validate with,
-
which would be our register validator.
-
The request will then pluck the data
-
off of our request itself,
-
provide it into our validator to validate with,
-
and then kick back that response to us
-
with that same validated type that we saw earlier.
-
This means that this line here is now our step one
-
as that's grabbing our request data and validating it.
-
So we can get rid of this line here as a whole.
-
And then for our createUser step,
-
we now have access to that same data right here.
-
So we can just provide in data there.
-
We no longer need to validate it again.
-
Simplifying our logic flow here a little bit.
-
Let's jump back into our browser one more time
-
just to make sure that all of this worked.
-
We'll give it a refresh.
-
Type in john [email protected]
-
and some invalid password.
-
Run there and everything still works A-okay.
-
Introduction
-
Fundamentals
-
2.0Routes and How To Create Them5m 23s
-
2.1Rendering a View for a Route6m 29s
-
2.2Linking Between Routes7m 51s
-
2.3Loading A Movie Using Route Parameters9m 17s
-
2.4Validating Route Parameters6m 6s
-
2.5Vite and Our Assets6m 38s
-
2.6Setting Up Tailwind CSS9m 5s
-
2.7Reading and Supporting Markdown Content4m 32s
-
2.8Listing Movies from their Markdown Files8m 51s
-
2.9Extracting Reusable Code with Services7m 4s
-
2.10Cleaning Up Routes with Controllers4m 52s
-
2.11Defining A Structure for our Movie using Models9m 38s
-
2.12Singleton Services and the Idea of Caching6m 11s
-
2.13Environment Variables and their Validation4m 16s
-
2.14Improved Caching with Redis10m 44s
-
2.15Deleting Items and Flushing our Redis Cache6m 46s
-
2.16Quick Start Apps with Custom Starter Kits6m 28s
-
2.17Easy Imports with NodeJS Subpath Imports8m 40s
-
-
Building Views with EdgeJS
-
3.0EdgeJS Templating Basics8m 49s
-
3.1HTML Attribute and Class Utilities6m 9s
-
3.2Making A Reusable Movie Card Component10m 24s
-
3.3Component Tags, State, and Props4m 53s
-
3.4Use Slots To Make A Button Component6m 56s
-
3.5Extracting A Layout Component5m 13s
-
3.6State vs Share Data Flow2m 59s
-
3.7Share vs Global Data Flow6m 7s
-
3.8Form Basics and CSRF Protection6m 13s
-
3.9HTTP Method Spoofing HTML Forms3m 3s
-
3.10Easy SVG Icons with Edge Iconify7m 57s
-
-
Database and Lucid ORM Basics
-
4.0Configuring Lucid and our Database Connection4m 3s
-
4.1Understanding our Database Schema9m 35s
-
4.2Introducing and Defining Database Migrations18m 35s
-
4.3The Flow of Migrations8m 28s
-
4.4Introducing Lucid Models5m 43s
-
4.5Defining Our Models6m 49s
-
4.6The Basics of CRUD11m 56s
-
4.7Defining Required Data with Seeders11m 11s
-
4.8Stubbing Fake Data with Model Factories13m 48s
-
4.9Querying Our Movies with the Query Builder15m 30s
-
4.10Unmapped and Computed Model Properties3m 24s
-
4.11Altering Tables with Migrations7m 6s
-
4.12Adding A Profile Model, Migration, Factory, and Controller2m 57s
-
4.13SQL Parameters and Injection Protection9m 19s
-
4.14Reusable Query Statements with Model Query Scopes8m 11s
-
4.15Tapping into Model Factory States9m 15s
-
4.16Querying Recently Released and Coming Soon Movies4m 59s
-
4.17Generating A Unique Movie Slug With Model Hooks7m 59s
-
-
Lucid ORM Relationships
-
5.0Defining One to One Relationships Within Lucid Models5m 49s
-
5.1Model Factory Relationships2m 54s
-
5.2Querying Relationships and Eager Vs Lazy Loading5m 17s
-
5.3Cascading and Deleting Model Relationships5m 16s
-
5.4Defining One to Many Relationships with Lucid Models6m 56s
-
5.5Seeding Movies with One to Many Model Factory Relationships5m 24s
-
5.6Listing A Director's Movies with Relationship Existence Queries8m 41s
-
5.7Listing and Counting a Writer's Movies8m 41s
-
5.8Using Eager and Lazy Loading to Load A Movie's Writer and Director5m 18s
-
5.9Defining Many-To-Many Relationships and Pivot Columns9m 48s
-
5.10Many-To-Many Model Factory Relationships4m 50s
-
5.11A Deep Dive Into Relationship CRUD with Models18m 5s
-
5.12How To Create Factory Relationships from a Pool of Data13m 55s
-
5.13How To Query, Sort, and Filter by Pivot Table Data9m 47s
-
-
Working With Forms
-
6.0Accepting Form Data12m 15s
-
6.1Validating Form Data with VineJS9m 29s
-
6.2Displaying Validation Errors and Validating from our Request7m 16s
-
6.3Reusing Old Form Values After A Validation Error2m 3s
-
6.4Creating An EdgeJS Form Input Component5m 28s
-
6.5Creating A Login Form and Validator5m 1s
-
6.6How To Create A Custom VineJS Validation Rule9m 7s
-
-
Authentication & Middleware
-
The Flow of Middleware7m 49s
-
Authenticating A Newly Registered User4m 14s
-
Checking For and Populating an Authenticated User2m 10s
-
Logging Out An Authenticated User2m 24s
-
Logging In An Existing User6m 54s
-
Remembering A User's Authenticated Session6m 55s
-
Protecting Routes with Auth, Guest, and Admin Middleware5m 36s
-
-
Filtering and Paginating Queries
Join The Discussion! (0 Comments)
Please sign in or sign up for free to join in on the dicussion.
Be the first to Comment!