adminjs icon indicating copy to clipboard operation
adminjs copied to clipboard

Lacking support of JSON fields

Open rivatove opened this issue 3 years ago • 2 comments

Describe the bug No data appears for MySQL JSON fields when using Prisma.

Installed libraries and their versions

To Reproduce Steps to reproduce the behavior:

  1. Have JSON field in one of your resources
  2. View it in dashboard
  3. No data appears

Expected behavior JSON field is supported (its data appears in the dashbord & is editable).

Screenshots https://prnt.sc/SIEr4FMIR48a

AdminJSOptions with schema Exactly as in docs: https://docs.adminjs.co/installation/adapters/prisma

rivatove avatar Dec 01 '22 00:12 rivatove

In non-mongoose adapters we're unable to retrieve JSON objects and determine their types automatically. You would have to modify this property's type in your resource options to be either:

  • mixed - it requires you to define subfields and doesn't have a dynamic structure but you're able to save JSONs with specific types conversion:
properties: {
  meta: { type: 'mixed' },
  'meta.name': { type: 'string' },
  'meta.timestamp': { type: 'number' },
  // etc
}
  • key-value - it loads your JSON from database as it is and allows you to add new keys, but all values are saved as text
properties: {
  meta: { type: 'key-value' },
}

dziraf avatar Dec 01 '22 07:12 dziraf

@dziraf

Okay, I tried this and was able to make the JSON data display correctly. To show nested JSON you need to combine 'mixed' with 'key-value', e.g: meta: { type: 'mixed' }, 'meta.request': { type: 'key-value' },

There are however several important issues with JSON fields right now.

1. You can't update resource if one of JSON fields is null.

Error: Argument X for data.X must not be null. Please use undefined instead.

Fix: This happens because you use null instead of Prisma's null values (e.g. Prisma.DbNull): https://www.prisma.io/docs/concepts/components/prisma-client/working-with-fields/working-with-json-fields#inserting-null-values

2. When you update a JSON field, all primitves are cast to string.

true ends up being "true", null becomes "", 25 changes to "25". This is very bad.

Fix: see below

3. You are required to define the JSON tree beforehand it order to work with it.

Instead of defining the type once for nested JSON you need to describe the tree as described in the beginning.

Fix: Add 'json' property type. When showing the value in the client, show it as is and only beautify the JSON. This is how Laravel Nova does it and it works perfectly (https://prnt.sc/9-qwjPSF1gQH).

rivatove avatar Dec 01 '22 16:12 rivatove