This is mostly me making a note for myself but I’ll make it public in case it helps anyone else. I needed to use a string as a template in the vein of template literals, which turned out to be harder than expected. Here’s the solution…
So we all know that ES6 introduced template literals via which we can write a string (with line breaks!) and tags where we want to replace in the values of variables. Very simple example below.
const a = 5;
const b = 10;
const template = `The values are a=${a} and b=${b}`
console.log(template)
// The values are a=5 and b=10
But there’s a catch if you were thinking of using this for any situation where the value of the template comes from a string – such as maybe if you have multilingual error messages coming from a database. Yes – there are other ways of accomplishing that, but go with me for the journey!
What we need is some way to turn a string into a template literal, then we can have the variable replacement happen. But it turns out that the general approach to this is to use eval. Given all the security concerns of using eval, I feel that I want to avoid this.
A better alternative is to provide a simple function to accomplish what JS does internally, and interpolate variables into the template string. Here’s an example taken from this SO answer.
// Given a string template formatted like a template literal,
// and an object of values, return the modified string.
function interpolateTemplate(template, args) {
return Object.entries(args).reduce(
(result, [arg, val]) => result.replace(`$\{${arg}}`, `${val}`),
template,
)
}
const a = 5;
const b = 10;
const templateStr = "The values are a=${a} and b=${b}"
console.log(interpolateTemplate(templateStr, {a:a, b:b}))
// The values are a=5 and b=10
As folks on SO point out, this solution does not support nesting which is a kind of multi-level capability offered by standard ES6 template literals. For my use-case I can live with that since this solution removes the clash of strings vs template literals.
Summary
We’ve seen a handy way to interpolate strings as templates and produce similar functionality to the ES6 template literals feature, with some tradeoffs. If you do need nested substitution, then there are handlebars-type libs that can help for that.
Thanks for reading.
VW. May 2023
Image by geraldo-stanislas at Unsplash.com