I need to save a json object like:
{
"name": "larry",
"mapping": {
"foo.bar": "bar"
}
}
however, Mongo prohibits you from saving keys that have $
or .
in them - reference.
To work around this, I made a utility that would replace the dots unicode \uff0e
:
export function replaceDots(obj, replace = true) {
if(obj === undefined || obj === null) return obj;
if(Array.isArray(obj)) {
const result = [];
for(const val of obj) {
result.push(this.replaceDots(val, replace));
}
return result;
} else if(typeof obj === 'object') {
const keys = Object.keys(obj);
const result = {};
for(const key of keys) {
let newKey;
if(replace) {
newKey = key.replace(/\./g, '\uff0e');
} else {
newKey = key.replace('\uff0e', '.');
}
const val = obj[key];
result[newKey] = this.replaceDots(val, replace);
}
return result;
}
return obj;
}
I can be certain that unicode will never be in these keys so its a safe approach for my use case. However, now everywhere where I GET or SAVE the model now, I have to call this transform on it like:
const newPlaybook = replaceDots(request.body);
const playbook = new Playbook(newPlaybook);
let result = await playbook.save();
result = replaceDots(result, false);
which is quite nasty and error prone, I tried using middleware and the toJSON
function to do the transformation but because I'm actually returning a new object, it was not very successful.
I was wondering if there was a better approach to handle this without having to manually call replace on each usage?