DEV Community

Maelig
Maelig

Posted on

TypeORM - insert Map as JSON

Guess what, if you want to store a beautiful ES6 Map in TypeORM you end up with a less beautiful result : {}.

Why you hate me JSON.stringify() ?

It's in fact explained in the JSON.stringify() doc but who reads it ?

Only enumerable own properties are visited. This means Map, Set, etc. will become "{}". You can use the replacer parameter to serialize them to something more useful.

Because we can't modify TypeORM's code, we have to find another solution.

Our case

We have an entity with a map property we want to store as json.

@Column({type: 'json'})
actions: Map<string, ActionsOnDomain>;
Enter fullscreen mode Exit fullscreen mode

but we end up with {} in our table, as you could have guessed 🙃

Solution please ?

We will have to use the transformer column's option.

@Column({
  type: 'json',
  transformer: new JsonColumnMapObjectTransformer()
})
actions: Map<string, ActionsOnDomain>;
Enter fullscreen mode Exit fullscreen mode

I externalised this transformer to be reused later.

We don't have to use JSON.stringify/parse because TypeORM will do it for us.

import { ValueTransformer } from 'typeorm/decorator/options/ValueTransformer';

export class JsonColumnMapObjectTransformer<T> implements ValueTransformer {
  // db -> entity
  from(value: Object): any {
    const entries = Object.entries(value);
    return new Map<string, T>(entries);
  }

  // entity -> db
  to(value: any): any {
    return Object.fromEntries(value);
  }
}
Enter fullscreen mode Exit fullscreen mode

and now everybody is happy and lived happily ever after

Top comments (0)