Reputation: 100070
Say I have template literal like so:
const templateLiteral = `string text ${expression} string text`
I want to dynamically evaluate the template literal into a finished string.
function toFoo(templateLiteral){
//returns "string text Foo string text"
return templateLiteral.evaluate('Foo');
}
function toBar(templateLiteral){
//returns "string text Bar string text"
return templateLiteral.evaluate('Bar');
}
function toBaz(templateLiteral){
//returns "string text Baz string text"
return templateLiteral.evaluate('Baz');
}
is there a way to do something like this with template literals, or am I just being dumb? (template.evaluate() is a made up function, but I am looking for that kind of functionality with JS!).
Upvotes: 14
Views: 7816
Reputation: 4681
Reusable and simplified templating function with dynamic values.
const contentTemplate = (template, dynamicValues, callback, selector) => {
const regex = /{{(.*?)}}/g;
const result = template.replace(regex, (match, captureKey) => {
return dynamicValues[captureKey] || '';
})
callback && callback(result, selector)
return result
}
const content = 'Hello, My is {{name}}, age is {{age}} and Im from {{city}}';
const dynamicValues = {
name: 'Amoos',
age: 28,
city: 'Paris'
}
const addContentFunction = ( tranformedContent, selector ) => {
const app = document.querySelector(selector)
app.innerHTML = tranformedContent ? tranformedContent : 'No content!'
}
contentTemplate(content, dynamicValues, addContentFunction, '#myId')
contentTemplate(content, {name: 'Rifat', age: 24, city: 'Berlin' }, addContentFunction, '.myClass')
<div id="myId"></div>
<hr />
<div class="myClass"></div>
Upvotes: 0
Reputation: 686
Tagged template strings could help in this scenario:
function toFoo(strings, ...values) {
console.log(strings[0]); // string text
console.log(strings[1]); // string text
console.log(values[0]); // <your-passed-expression>
// TODO: Do your manipulation
}
const val = toFoo`string text ${expression} string text`;
strings
contains the "normal" tokens of the line and values
are the "variable" parts. Please note that you have to concatenate the string manually.
Upvotes: 1
Reputation: 100070
The best way to do this is quite obvious, simply reverse the situation given by the question. You just need to wrap the template literals in a function, and then you will delay evaluation until you pass in the desired params. It's that simple.
function evaluteTemplateLiteral(bar){
return `foo ${bar} baz`;
}
now if you wanted to get fancier, you could create this:
function evaluateGeneric(vals, fn){
return fn.apply(null, vals);
}
and you would use the above like so:
evaluateGeneric(['brown','fox','cholo'], function(){
return `the quick ${arguments[0]} fox ${arguments[1]}`;
});
Upvotes: 12
Reputation: 691
i would just call eval, you are evaluating code anyway when using template strings
Upvotes: 0