Objection.js: Handle date type

Created on 2 Mar 2016  路  2Comments  路  Source: Vincit/objection.js

Thanks for excellent ORM.

I came across with next issue: I use date type in my postgre table and it seems that value is written correctly but when I read value from object I get something like
expire_at: Sat Feb 27 2016 19:00:00 GMT-0500 (EST)

Should I handle date type somehow especially?

Most helpful comment

Objection.js doesn't do any type mapping automatically. Especially the javascript Date type sucks so hard that I never use it :smile:

You have at least two options here:

Option 1: Add a mapper to the db client

For postgres pg client you can do something like this:

var types = require('pg').types
var TIMESTAMPTZ_OID = 1184
var TIMESTAMP_OID = 1114
var parseFn = function(val) {
   return val === null ? null : new Date(val)
}
types.setTypeParser(TIMESTAMPTZ_OID, parseFn)
types.setTypeParser(TIMESTAMP_OID, parseFn)

Option 2: Add mapping to objection model:

class MyBaseModel extends objection.Model {
  ...
  $parseDatabaseJson(json) {
    json = super.$parseDatabaseJson(json);
    json.expire_at = json.expire_at && new Date(json.expire_at);
    return json;
  }
  ...
}

Or if you use jsonSchema you can write a more generic approach like this:

class MyBaseModel extends objection.Model {
  ...
  $parseDatabaseJson(json) {
    json = super.$parseDatabaseJson(json);
    _.each(this.constructor.jsonSchema.properties, (schema, prop) => {
      if (schema.format === 'date') {
        json[prop] = json[prop] && new Date(json[prop]);
      }
    })
    return json;
  }
  ...
}

All 2 comments

Objection.js doesn't do any type mapping automatically. Especially the javascript Date type sucks so hard that I never use it :smile:

You have at least two options here:

Option 1: Add a mapper to the db client

For postgres pg client you can do something like this:

var types = require('pg').types
var TIMESTAMPTZ_OID = 1184
var TIMESTAMP_OID = 1114
var parseFn = function(val) {
   return val === null ? null : new Date(val)
}
types.setTypeParser(TIMESTAMPTZ_OID, parseFn)
types.setTypeParser(TIMESTAMP_OID, parseFn)

Option 2: Add mapping to objection model:

class MyBaseModel extends objection.Model {
  ...
  $parseDatabaseJson(json) {
    json = super.$parseDatabaseJson(json);
    json.expire_at = json.expire_at && new Date(json.expire_at);
    return json;
  }
  ...
}

Or if you use jsonSchema you can write a more generic approach like this:

class MyBaseModel extends objection.Model {
  ...
  $parseDatabaseJson(json) {
    json = super.$parseDatabaseJson(json);
    _.each(this.constructor.jsonSchema.properties, (schema, prop) => {
      if (schema.format === 'date') {
        json[prop] = json[prop] && new Date(json[prop]);
      }
    })
    return json;
  }
  ...
}

Thank you very much. I like the first option.
I've fixed problem by replacing Date type to moment something like this

const DATE_OID = 1082;
const types = require('pg').types;
types.setTypeParser(DATE_OID, val => val == null ? null : moment(val));

Additionally I found interesting discussing related similar problem.

Was this page helpful?
0 / 5 - 0 ratings