Home > Enterprise >  422 error trying to save json data to the database
422 error trying to save json data to the database

Time:04-16

I'm trying to save data to my MySql db from a Node method. This includes a field called attachments.

console.log(JSON.stringify(post.acf.attachments[0])); returns:

{
  "ID": 4776,
  "id": 4776,
  "title": "bla",
  "filename": "bla.pdf",
  "filesize": 1242207,
  "url": "https://example.com/wp-content/uploads/bla.pdf",
  "link": "https://example.com/bla/",
  "alt": "",
  "author": "1",
  "description": "",
  "caption": "",
  "name": "bla",
  "status": "inherit",
  "uploaded_to": 0,
  "date": "2020-10-23 18:05:13",
  "modified": "2020-10-23 18:05:13",
  "menu_order": 0,
  "mime_type": "application/pdf",
  "type": "application",
  "subtype": "pdf",
  "icon": "https://example.com/wp-includes/images/media/document.png"
}

This is indeed the data I want to save to the db:

await existing_post.save({
    ...
    attachments: post.acf.attachments[0],
)};

However, the attachments field produces a 422 server error (if I comment out this field, the other fields save without a problem to the db). I'm not getting what is causing this error. Any ideas?

I've also tried

await existing_post.save({
    ...
    attachments: post.acf.attachments,
)};

but then it seems to just save "[object Object]" to the database.

The field in the database is defined as text. I've also tried it by defining the field as json, but that made no difference.

exports.up = function (knex, Promise) {
    return knex.schema.table("posts", function (table) {
        table.longtext("attachments");
    });
};

CodePudding user response:

The 422 error code is about the server unable to process the data you are sending to it. In your case, your table field is longtext when post.acf.attachments seems like an object. That's why it saves [object Object] to your db (It is the return value of the toString() method).

Try using

await existing_post.save({
    ...
    attachments: JSON.stringify(post.acf.attachments),
)};

MySQL and knex both support the JSON format, I'd suggest you change the field to json. (See knex docs and mysql 8 docs). You'll stiil need to stringify your objects tho.

EDIT: I just saw that Knex supports jsonInsert (and plenty other neat stuff) as a query builder that should be useful for you. Mysql also support a large range of cool stuffs for handling jsons

In addition, when you fetch the results in the database, you'll need to parse the JSON result to get an actual JSON object:

const acf = await knex('posts').select('acf').first();
const attachment = JSON.parse(acf.attachment;

Knex also provide jsonExtract that should fill your needs (See also the mysql json_extract

  • Related