DEV Community

MemphisNguyen
MemphisNguyen

Posted on

AdonisJS validate file in Object

This is my experience about validating request data using AdonisJS validator and the solution for it. I can't easily find an article about this issue so I decide to write this so that others which have the same issue could find the solution easier.

Context

This issue happened when I had a data block that need to submit to the backend to handle. Its format looks like this

{
  "users": [
    {
      "name": "John Doe",
      "avatar": <File>
    },
    ...
  ]
}
Enter fullscreen mode Exit fullscreen mode

And following the documents from AdonisJS, I use this snippet to validate the data

params = await request.validate({
  schema: schema.create({
    users: schema.array().members(
      schema.object().members({
        name: schema.string({ trim: true }),
        avatar: schema.file({
          size: '10mb',
          extnames: ['jpg', 'heic']
        }),
      })
    ),
  }),
})
Enter fullscreen mode Exit fullscreen mode

Problem

The problem is that submitted data in the backend will be stored by AdonisJS in 2 parts, request.all() and request.allFiles(). So the data will be

request.all() : { "users": [ { "name": "John Doe" } ] }
request.allFiles(): { "users": [ { "avatar": <File> } ] }
Enter fullscreen mode Exit fullscreen mode

And to running the validation, these data pieces will need to be merged to make sure it pass the rules.
Unfortunately, following AdonisJS's author idea that deep merge will affect to the performance of the framework. Therefore, shallow merge is used to combine them and it looks like this

data = {
  ...body,
  ...files,
}
Enter fullscreen mode Exit fullscreen mode

And you know what happened. After the merge, user item only has avatar property.

Solution

As the author suggestion in the comment about, I've change the way to validate the data by perform deep merge data by using lodash merge and use AdonisJS standalone validator to validate the merged data

import lodashMerge from 'lodash/merge'
import { validator } from '@ioc:Adonis/Core/Validator'
...
allData = lodashMerge({}, request.all(), request.allFiles())

params = await validator.validate({
  data: allData,
  schema: schema.create({
    users: schema.array().members(
      schema.object().members({
        name: schema.string({ trim: true }),
        avatar: schema.file({
          size: '10mb',
          extnames: ['jpg', 'heic']
        }),
      })
    ),
  }),
})
Enter fullscreen mode Exit fullscreen mode

And that's how I got the params as same as the way it's submitted.

Readers, let me know if you can see any other way to resolve this issues.

Thanks for reading.

Top comments (0)