16

I discovered Javascript ES6 Template Literals today. Just one word: Awesome!

Question: How to store and load Template Literals as JSON? I load some files via XHR, followed by some JSON.parse() which doesn't support ` instead of ", so it seems one can't save Template Literals directly in the files.

Goal: To use this for dynamic strings and translation and to get rid of confusing stuff like ("Hello " + username + "! How are you?") which requires multiple strings to be stored for just one message, and instead save my stuff beautifully and simple as

`Hello, ${username}! How are you?`

where username points to the dynamic variable with the same name. Is that possible? If yes, how to achieve this? It's okay if i have to use a function to somehow convert the strings into Template Literals as long as it doesn't hit hard on the overall performance, but I would like to at least avoid eval.

trincot
  • 317,000
  • 35
  • 244
  • 286
nora
  • 203
  • 1
  • 3
  • 8
  • 8
    These literals are code not strings. You can not store them as JSON. but you can use functions. `var tplHello = ({username}) => \`Hello, ${username}! How are you?\`` and use it as `var data={ username: "foo" }, text = tplHello(data);` – Thomas Apr 06 '17 at 17:29
  • 2
    @Thomas: Thanks. It seems i have confused template literals with "dynamic strings", just as you say. According to https://stackoverflow.com/questions/29771597/how-can-i-construct-a-template-string-from-a-regular-string converting a string into a template literal would be implicitly the same as **eval** as variable lookup always needs code to be executed. Seems like my hope for an easy translation system or "dynamic "strings" was fueled by a misconception. Off-Topic: I guess using RegEx for replacing %username (or similar) in the strings would fit what i want to achieve better. – nora Apr 06 '17 at 17:48

4 Answers4

12

You can create your own function to parse template literal,

function stringTemplateParser(expression, valueObj) {
  const templateMatcher = /{{\s?([^{}\s]*)\s?}}/g;
  let text = expression.replace(templateMatcher, (substring, value, index) => {
    value = valueObj[value];
    return value;
  });
  return text
}

console.log(stringTemplateParser('my name is {{name}} and age is {{age}}', {name: 'Tom', age:100}));


// output 'my name is Tom and age is 100'
Manasvi Sareen
  • 916
  • 7
  • 17
  • to use the ${variable} format, use this function instead: `function stringTemplateParser(expression, valueObj) { const templateMatcher = /\${\s?([^{}\s]*)\s?}/g; let text = expression.replace(templateMatcher, (substring, value, index) => { value = valueObj[value]; return value; }); return text }` – howMuchCheeseIsTooMuchCheese Oct 08 '21 at 11:49
4

You could always use JSON.stringify to enclose dynamic data:

const data = 'some value';
JSON.stringify({
  data,
});
// expected: "{\"data\": \"some value\"}"
ElPepe
  • 89
  • 1
  • 5
1

I found it easier to separate the problem in a few substrings of JSON. Create the key "message" and this key stores parts of the message. It also works well for i18n.

{
  "message" : {
    "_0": "first part ",
    "_1": "after first variable. ",
    "_2": "after another variable"
  }
}

And then, after decoding it, you can access it like ${message._0}${variable}${message._1}${var2}${message._2}

0

Try json-templates. Looks like exactly what you're looking for.

zmf
  • 542
  • 6
  • 9