1

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?

amcdnl
  • 8,470
  • 12
  • 63
  • 99
  • do you need or want to? saving `foo` as array and having foo["bar"] doesn't help? – Elmer Dantas Mar 21 '17 at 12:17
  • It needs to be persisted in the same data structures if at all possible – amcdnl Mar 21 '17 at 12:20
  • Sorry...I really can't see any better approach. [Here](http://stackoverflow.com/questions/8429318/how-to-use-dot-in-field-name) you can find another guys discussing a similar problem. Kind regards – Elmer Dantas Mar 21 '17 at 12:27
  • Thanks! I'm ok with doing the replace, just need a cleaner way to implement it rather than manually doing it. – amcdnl Mar 21 '17 at 12:41

0 Answers0