Module

flat

The AdminJS Data model

Before you dive into the details of the flat helpers, let me briefly introduce the way how the database data is stored in AdminJS.

The Simple Case

On the backend all the information from DataBase tables/collections goes to {@BaseRecord#params} object. Usually, it is a {key: value} store where key is a table name, and value could be either a string, a number, or an instance of Date() etc.

On the Frontend - these values go to the corresponding RecordJSON.params property.

This is an example params property in the "simple case":

params: {
  name: 'John',
  surname: 'Doe',
  age: 28,
}

The Real World Case

In the real world:

  • databases have nested JSONB properties or Mixed Schemas
  • developers would like to send more complicated data from the Fronted to the backend as arrays.

To achieve that we "flatten" all the data before saving them to params property.

So in the real world params could look like:

params: {
  name: 'John',
  surname: 'Doe',
  age: 28,
  // nested objects
  'auth.facebook': 'some login token',
  'auth.twitter': 'twitter login token',
  // arrays
  'interests.0': 'running',
  'interests.1': 'jogging',
}

and all the data can be even nested on the deeper levels.

Why we did that?

An alternative solution would be to store an entire raw object and don't care. But there are 2 reasons why we picked this one.

1. storing selected data in the database

If you send to the ORM unflatten save request like this:

Model.save({{ auth: { facebook: 'newFacebookToken' } }})

it will override an entire auth property, so from the example above, we will lose auth.twitter.

In the second (flatten) case:

Model.save({ `auth.facebook`: 'newFacebookToken' }})

ORM should keep the value of the auth.twitter

The above is true for Mongoose adapter which is the most advanced regarding handing mixed values

2. Sending data between the Frontend and the Backend in FormData format

AdminJS allows you to upload Files from the Frontend to the Backend. The most optimal way of doing that is by using FormData. But, this requires that values for all the fields are send in [key: string]: string form. And this, as you might guess, fits perfectly to our flatten params logic.

Consequences

Flattening in AdminJS has its consequences everywhere where you use

because instead of raw object you have it's flatten version.

Also, (as mentioned) the payload send to the backed is also flattened.

There you should use helpers gathered in flat

View Source adminjs/src/utils/flat/flat-module.ts, line 11

Methods

# static filterOutParams(params, properties) → {FlattenParams}

Parameters:
Name Type Description
params FlattenParams
properties string | Array.<string>

View Source adminjs/src/utils/flat/filter-out-params.ts, line 10

# static get(params, propertyPathopt, options) → {any}

Parameters:
Name Type Attributes Description
params FlattenParams

flatten params from which property has to be taken

propertyPath string <optional>

name of the property

options GetOptions

options

View Source adminjs/src/utils/flat/get.ts, line 17

when property key exists directly it returns what is inside, otherwise it tries to find any nested objects and returns them

any

# static merge(params) → {FlattenParams}

Merges params together and returns flatten result
Parameters:
Name Type Description
params any
...mergeParams Array.<any>

View Source adminjs/src/utils/flat/merge.ts, line 12

# static removePath(params, …properties) → {FlattenParams}

Parameters:
Name Type Attributes Description
params FlattenParams
properties string <repeatable>

View Source adminjs/src/utils/flat/remove-path.ts, line 14

# static selectParams(params, properties, optionsopt) → {FlattenParams}

Parameters:
Name Type Attributes Description
params FlattenParams
properties string | Array.<string>
options GetOptions <optional>

View Source adminjs/src/utils/flat/select-params.ts, line 11

# static set(params, propertyPath, valueopt) → {FlattenParams}

Parameters:
Name Type Attributes Description
params FlattenParams
propertyPath string
value any <optional>

if not give function will only try to remove old keys

View Source adminjs/src/utils/flat/set.ts, line 22

# pathToParts(propertyPath, options) → {PathParts}

Parameters:
Name Type Description
propertyPath string
options PathToPartsOptions

View Source adminjs/src/utils/flat/path-to-parts.ts, line 11

PathParts

Type Definitions

object

# FlattenParams

Type of flatten params.
Properties:
Name Type Description
{...} FlattenValue

View Source adminjs/src/utils/flat/flat.types.ts, line 18

Union

# FlattenValue

Available types for flatten values. This is an Union of types:
  • string
  • boolean
  • number
  • Date
  • null
  • [] (empty array)
  • {} (empty object)
  • File

View Source adminjs/src/utils/flat/flat.types.ts, line 3

object

# GetOptions

Properties:
Name Type Attributes Description
includeAllSiblings boolean <optional>

Indicates if all the "less related" siblings should be included. This option takes care of, fetching elements in nested arrays. Let's say you have keys: nested.0.array.0 and , nested.1.array.0.. With includeAllSiblings` you will fetch all nested.N.array elements.

View Source adminjs/src/utils/flat/flat.types.ts, line 27

object

# PathToPartsOptions

Properties:
Name Type Attributes Description
skipArrayIndexes boolean <optional>

Indicates if array indexes should be skipped from the outcome.

View Source adminjs/src/utils/flat/path-to-parts.ts, line 30