Jack Jack - 1 year ago 41
Javascript Question

How to write a function that takes a string and object and interpolates that object in the string?

Hi everyone I need to write a function that takes a string and object and interpolates that object in the string so something like this

// interpolate("Its {weather} outside", {weather: 'damn Hot'})
// returns 'It's damn hot outside'

// interpolate( "Hi my name is {name}", {name: 'John'});
// returns 'Hi my name is John'

It should also no matter how deep the object goes so a case like this

// interpolate("Hi my name is {contact.name}", {contact: {name: 'john'}});

Im a little stuck and at first I tried splitting up the string into an array then trying to fit the object value in the array then join that back together but that has not worked for all test cases, can someone help me write this function and explain their solution please? Thankyou

so I tried something like this but does not really work for all test cases, this is a template literal but the function should just work giving those values as arguments on its own, otherwise I'm pretty stuck . .

function interpolate(strings, ...keys) {
return (function(...values) {
var dict = values[values.length - 1] || {};
var result = [strings[0]];
keys.forEach(function(key, i) {
var value = Number.isInteger(key) ? values[key] : dict[key];
result.push(value, strings[i + 1]);
return result.join('');

var t1Closure = interpolate`${0}${1}${0}!`;
t1Closure('Y', 'A'); // "YAY!"
var t2Closure = interpolate`${0} ${'foo'}!`;
console.log(t2Closure('Hello', {foo: 'World'})); // "Hello World!"

ok I'm getting closer so I separated the problem into two functions and need to combine them, the only thing is I'm not sure how to get the last use case to work without template literals

var something = "something";
var sub = function(str) {
return str.replace(/#\{(.*?)\}/g,
function(whole, expr) {
return eval(expr)

console.log(sub("hello #{something}"));

var objectValue = function(str, obj){

for(key in obj) {
if(obj.hasOwnProperty(key)) {
var value = obj[key];
return str + value;

console.log(objectValue("hi my name is ", {contact: {name: 'john'}}));

Answer Source

Using the dreaded eval

If you control the string that you pass and consider it safe, you can use eval:

function interpolate (str, obj)  {
    return str.replace(/\{(.*?)\}/g, function (_, ref) {
        return eval('obj.' + ref);

var output = interpolate("Its {weather} outside", {weather: 'damn Hot'});

output = interpolate("Hi my name is {contact.name}", {contact: {name: 'john'}});

output = interpolate("The highest bid is {rank[0].bid}", {rank: [{bid: 900}, {bid:600}]});

Be aware that if given a string like '{x;alert("hi")}', the above function would execute that alert, or any code that is put instead. So this is not a good solution if the string is provided (or can be altered) by the user.

Template Literals

It does not follow your function descriptor, but template literals already offer the functionality you are looking for:

var weather = 'damn Hot';
var output = `It's ${weather} outside`;

var contact = {name: 'john'};
var output = `Hi my name is ${contact.name}`;