Ready to get started?

Join Adocasts Plus for $8/mo, or sign into an existing Adocasts Plus account, to get access to all of our lessons.

robot mascot smiling

Form Validation & Displaying Errors

@tomgobich
Published by
@tomgobich
In This Lesson

We'll add validation to our POST handler for our register route. We'll then update our form fields to check for and display any validation errors that may have occurred.

Chapters

00:00 - Adding & Defining Our Register Validator
02:04 - Inspecting How Validation Errors Are Provided
03:30 - Access & Displaying Validation Errors

Join the Discussion 11 comments

Create a free account to join in on the discussion
  1. @hsn

    Hey, my app doesn't provide validation errors right away. On the response tab it says "No content avaliable because this request was redirected."

    And there is no attr section on vue dev tools. I checked and it looks like we have exactly same code. Is it something about different versioning or something?

    Great course btw! Thanks.

    2
    1. Responding to hsn
      @tomgobich

      Hey hsn! When you're redirecting, is the response type a 303? Inertia expects redirect statuses to be 303 to work properly, and the AdonisJS adapter should automatically take care of this for you. So, if that isn't happening then something is likely misconfigured in your project.

      As for the attr section, if all items being passed into a page component are registered as props within the page, then there won't be attrs to display as everything will be under props. attrs in Vue captures non-registered prop data. For example:

      <template>
        <Header :user="user" :theme="blue" />
      </template>
      
      ---
      
      <script setup lang="ts">
      // Header.vue
      defineProps<{
        theme: string
      }>()
      <script>
      
      <template>
        <span>Hello</span>
      </template>
      Copied!

      In the above theme is a registered prop, so it'll be under props, but not attrs. Meanwhile, user is not a registered prop, but is being passed into the header. Therefore, it won't be within props, but rather attrs.

      That is the only thing coming to mind as to why the attrs may differ.

      Hope this helps!!

      0
      1. Responding to tomgobich
        @hsn

        Hey Tom, thanks for fast reply. Actually i think i checked if we have anything different so far and it looks like we have same conf. But my response type is 302 found.

        And thanks for the attrs explanation, i meant i tried a few things like removing defineProps to see if errors are making it to frontend as attrs but they were not. Then i removed all my attempts again, and got the errors on the frontend(idk why they were not tere and now idk how i fixed it (: ) even tho now i am getting validation errors, status code is still 302.

        I will check on the repo to see what is the reason it's coming as 302.

        Thanks.

        1
        1. Responding to hsn
          @tomgobich

          AdonisJS' automatic 302 to 303 conversion happens via the Inertia Middleware that comes with the package. You'll want to make sure it is configured as server middleware inside the start/kernel.ts file.

          I reckon the 302 issue might be related to your errors not originally populating. If you're able to and need further help digging into it, feel free to share the repo and I can take a look.

          0
  2. @nonwiz

    Hi, I'm not sure if there is something that I missed, somehow my adonisjs application doesn't trigger the global exception handling, when vine throw a validation error, the server just stop. I've checked the middleware, global exceptions/handlers, it is also there :(

    The server just died once there's a validation issue, it seems like it is not being wrapped by try catch, which I suppose the global exception handler should've take care of that.

    I'm using request.validateUsing(…)

    2
    1. Responding to nonwiz
      @nonwiz

      Found the issue, it happened because I forgot to add "await" in front of request.usingValidatior…

      1
      1. Responding to nonwiz
        @tomgobich

        Hi nonwiz! Happy to hear you were able to get it figured out! 😊

        1
  3. @ruslan-mr

    Hey! How can I send custom errors? I'm validating certFile and trying to return a response with response.unprocessableEntity, but I’m getting an error: "All Inertia requests must receive a valid Inertia response, but a plain JSON response was received." Any ideas?

      async store({ inertia, request, response }: HttpContext) {
        const data = await request.validateUsing(createPostCalendar)
        console.log('data', { data })
        const certFile = request.file('certFile', {
          size: '1mb',
          extnames: ['pfx'],
        })
    
        if (certFile) {
          if (!certFile.isValid) {
            // Not working, got error.
            return response.unprocessableEntity({
              errors: { certFile: certFile.errors },
            })
          }
          await certFile.move(app.makePath('storage/uploads'), {
            name: `${cuid()}.${certFile.extname}`,
          })
          Object.assign(data, { certFile: certFile.fileName })
        }
        await Calendar.create({ ...data })
        return response.redirect('/panel')
      }
    Copied!
    1
    1. Responding to ruslan-mr
      @tomgobich

      Hey Ruslan!

      Yeah, as we'll discuss in lesson 3.6, covering Inertia's limitations, when Inertia sends a request it requires a specific format for the response. Otherwise, you'll get the error you mentioned above.

      Because of this, Inertia doesn't want you to return 422 responses. Rather, they want you to flash the errors to the session and redirect the user back to the page.

      So, if certFile is a form field, you could manually send back an error like this:

      async store({ inertia, request, response, session }: HttpContext) {
        // ...
          
        if (!certFile.isValid) {
          // not sure if certFile.errors is already an array or not
          // certFile type should be string[] for consistency with AdonisJS
          session.flash('errors', { certFile: [certFile.errors] })
          return response.redirect().back()
        }
      
        // ...
      }
      Copied!

      Otherwise, if you just need a general exception-like error, separate from validation, you could do:

      async store({ inertia, request, response, session }: HttpContext) {
        // ...
          
        if (!certFile.isValid) {
          session.flash('errorsBag', { E_UNPROCESSABLE_ENTITY: certFile.errors })
          return response.redirect().back()
        }
      
        // ...
      }
      Copied!

      Hope this helps!

      1
  4. @kite

    It would be great if the right hand sidebar showed completed courses. Maybe you can turn the circle that contains the module number green or something similar

    1
    1. Responding to kite
      @tomgobich

      Yes, it absolutely would, thank you very much kite!! I have no clue how I overlooked that. I'll try and get this added tomorrow after work!

      1