Description
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.