Skip to content

Ability to pass custom options to JSON serialization that will be also be passed to children/relations #1374

Closed
@seanjrankin

Description

@seanjrankin

Often I find myself needing to alter the JSON results of serialization.

For example:
Perhaps I have a model 'ModelA' with attributes 'name' and 'secret'

I would like to be able to alter the results of toJSON by providing some options:

myModel.toJSON({ isGuest: true })
would yield

{
  "name": "Bob"
} 

But if isGuest was not present or false:

{
  "name": "Bob",
  "secret": "123"
} 

Looking through the API and code, I can't find a proper way to do this. I'm aware of $omitFromJson and objection-visibility, but those don't allow you to provide custom options. I also need this option to propagate down to all children/relations.

Am I missing something?

A relatively simple solution I came up with is like so (I could make a PR):
in objection.js/lib/model/modelToJson.js

function toJson(model, optIn) {
  const modelClass = model.constructor;

  const opt = {
    virtuals: getVirtuals(optIn),
    shallow: isShallow(optIn),
    omit: getOmit(optIn, modelClass),
    pick: null,
    omitFromJson: model.$omitFromJson(optIn.custom) || null,
    cloneObjects: modelClass.cloneObjectAttributes,
    custom: optIn.custom
  };

  let json = toExternalJsonImpl(model, opt);
  json = model.$formatJson(json);

  return json;
}

I simply allow a 'custom' option to be passed into toJSON, and passed along to $omitFromJson

I can then do something like:

export class ModelA extends BaseModel {
    $omitFromJson(options) {
        if (options && options.isGuest) {
            return ['secret'];
        } else {
            return null;
        }
    };
}

Alternatively, this custom option could be passed to $formatJson instead (as a second, optional parameter).

Let me know if this makes sense. I could make a PR that could flexibly handle most inputs to 'custom'. With the exception of promises, which I think should be left out of the serialization flow.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions