Reputation: 3596
Say I have a variable str
var str = "123"
Now I could do console.log(`Hello ${str}`)
and it will print Hello 123
Now I have another variable strnew
var strnew = 'Hello ${str}'
Note (based on answers/comments) - strnew
is read from a file, so its always a string and cant be replaced with `
How do I console.log(...)
to print Hello 123
Is it possible wihtout any kind of eval()
Upvotes: 32
Views: 24149
Reputation: 2554
I built off of @georg's answer above for a typescript solution:
public renderTemplate(templateStr: string, args: any): string {
templateStr = templateStr.replace(/`/g, '\\`');
const keys = Object.keys(args);
const fn = new Function(...keys, 'return `' + templateStr + '`');
return fn(...keys.map(key => args[key]));
}
The usage is virtually the same as well.
Upvotes: 0
Reputation: 214959
With something as simple as ${str}
you can use a simple string replacement:
var template = (tpl, args) => tpl.replace(/\${(\w+)}/g, (_, v) => args[v]);
var tpl = 'Hello ${str} and ${other}';
console.log(template(tpl, {str: 'foo', other: 'bar'}));
In a general case, no, not possible without eval (short of writing your own js interpreter), because ${...}
can contain arbitrary expressions.
For completeness' sake, here's the eval solution:
var template = function(tpl, args) {
var keys = Object.keys(args),
fn = new Function(...keys,
'return `' + tpl.replace(/`/g, '\\`') + '`');
return fn(...keys.map(x => args[x]));
};
function test() {
var myTpl = 'Hello ${str + "!"} and ${other.toUpperCase()}';
console.log(template(myTpl, {str: 'foo', other: 'bar'}));
}
test();
Upvotes: 36
Reputation: 4260
Thanks to this answer, here is a bit of black magic code that achieves what you want. Disclaimer - this is for fun / very limited and exotic application. It is likely to be very slow and break down on lots of edge cases, but with a limited scope of your question it works.
function getString(){
return "calculating ${foo} + ${bar} = ${foo + bar}";
}
var localEnvironmentProxy = new Proxy({}, {
has(target, prop) { return true; },
get(target, prop) { return (prop in target ? target : window)[prop]; }
});
with(localEnvironmentProxy){
var foo = 1;
var bar = 2;
var templString = getString();
var fnFullText = 'with(arguments[0]){ return `' + templString + '`;}';
var tempalteFn = new Function(fnFullText);
console.log(tempalteFn(localEnvironmentProxy));
//calculating 1 + 2 = 3
}
Upvotes: 0
Reputation: 525
You can use function instead of just string.
var strnew = function(str){
return `Hello ${str}`;
}
var str = "123";
console.log(strnew(str))
Upvotes: 1