Search code examples
javascripttemplatesobjectlodash

JS Replace Placeholder value in object


I have templates, where placeholders are specified as below. (.event.id, .event.properties.file, ...)

Lo and behold, I want to replace the placeholders in the templates with the values of the event-object below.

var templates = [
  {
    a:"1",
    a2: {some:"other Obj"},
    a3: ["or","array"],
  
    b: ".event.id",
    b2: "'.event.name' and more strings",
  },
  {
    dontKnowKeys: "of where the .event will be in",
    mightNotBeHere: "no placeholder here",
    butHereAgain: ".event"
    andSomeDeep: ".event.properties.file is Full"
  }
];

var event = {
  id: "1234-uuid-something",
  name: "I Am an awesome Event",
  properties: {
    file: "/root/foo",
    type: "error"
    }
  };


// First thought (pretty dirty, huh?)
JSON.parse(JSON.stringify(templates).replace(someMagicRegex, event))

// Second thought
templates = templates.map((tpl) => {
  return _.values(tpl).replace('.event.([a-z]+)',event["$1"]);
};

But that does not work for the properties.file key.

Additionally, what if the hierarchy gets arbitrarily longe .event.properties.file.cwd.path

After all I would like to have the following objects:

var out = [
  {
    a:"1",
    a2: {some:"other Obj"},
    a3: ["or","array"],
  
    b: "1234-uuid-something",
    b2: "'I Am an awesome Event' and more strings",
  },
  {
    dontKnowKeys: "of where the {\"id\":\"1234-uuid-something\",\"name\":\"I Am an  awesome Event\",\"properties\":{\"file\":\"/root/foot\",\"type\":\"error\"}} will be in",
    mightNotBeHere: "no placeholder here",
    butHereAgain: "{\"id\":\"1234-uuid-something\",\"name\":\"I Am an  awesome Event\",\"properties\":{\"file\":\"/root/foot\",\"type\":\"error\"}}"
    andSomeDeep: "/root/foo is Full"
  }
];


Solution

  • Tried a solution for you . Try out

    note : this will only works for your current template structure with simple arrays & objects . And regex need space after key selection. change it according to your need.

    var templates = [
      {
        a: "1",
        a2: {some: "other Obj"},
        a3: ["or", "array"],
    
        b: ".event.id",
        b2: "' .event.name ' and more strings",
      },
      {
        dontKnowKeys: "of where the .event will be in",
        mightNotBeHere: "no placeholder here",
        butHereAgain: ".event.properties.type.depth.key",
        andSomeDeep: ".event.properties.file is Full"
      }
    ];
    
    var event = {
      id: "1234-uuid-something",
      name: "I Am an awesome Event",
      properties: {
        file: "/root/foo",
        type: {depth:{key:"i am deep"}}
      }
    };
    
    
    // First thought (pretty dirty, huh?)
    //JSON.parse(JSON.stringify(templates).replace(someMagicRegex, event))
    
    // Second thought
    templates = templates.map((tpl) => {
      return handleObject(tpl);
    });
    
    function handleObject(obj) {
      for (let keyname in obj) {
        obj[keyname] = checkTypes(obj[keyname])
      }
      return obj;
    }
    
    // assume you have objects and arrays also
    function checkTypes(value) {
      if (typeof value === 'string') {
           return replaceVal(value);
      } else if (_.isArray(value)) {
        //assume array has only strings
         return value.map((d)=>replaceVal(d))
      } else if (_.isObject(value)) {
        return handleObject(value);
      }
    }
    
    
    function replaceVal(str) {
      //console.log(str);
      return str.replace(/.event.([^\s]+)/, (match,capture)=>_.get(event,capture))
    }
    
    console.log(templates);
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>