Shared Chat•
GPT-4

Exec Templates for Arrays

August 6, 2023
Write a JavaScript function like this: executeTemplates(template, arrayOfObjects) It takes a template which is a JavaScript string like this: Hello ${title} how are you? ${body} Then it executes that template (as if it was a tagged template literal) against each of the objects in the array in turn, creating an array of string results which it returns
ChatGPT

Sure! You can use the replace method to replace template literals in a string using properties from an object. Here's a function that takes a template string and an array of objects and returns an array of strings with the templates executed against each object:

javascript
function executeTemplates(template, arrayOfObjects) { return arrayOfObjects.map(obj => { return template.replace(/\$\{(\w+)\}/g, (match, p1) => { return obj[p1]; }); }); } // Example usage: const template = 'Hello ${title} how are you? ${body}'; const arrayOfObjects = [ { title: 'Mr. Smith', body: 'I am fine' }, { title: 'Mrs. Johnson', body: 'Doing well' } ]; console.log(executeTemplates(template, arrayOfObjects)); // Output: // ['Hello Mr. Smith how are you? I am fine', 'Hello Mrs. Johnson how are you? Doing well']

This code uses a regular expression to find all instances of ${...} in the template string and replace them with the corresponding property from the current object.

No I want it to be the equivalent of running this: `Hello ${title} how are you? ${body}` Except that template comes from a string passed in as template
ChatGPT

I see, you want to evaluate the template string in the context of the provided objects. This requires dynamically creating and evaluating a function for each object, so you can make use of JavaScript's template literals.

Here's how you can achieve that:

javascript
function executeTemplates(template, arrayOfObjects) { return arrayOfObjects.map(obj => { const keys = Object.keys(obj); const values = Object.values(obj); const templateFunction = new Function(...keys, `return \`${template}\`;`); return templateFunction(...values); }); } // Example usage: const template = 'Hello ${title} how are you? ${body}'; const arrayOfObjects = [ { title: 'Mr. Smith', body: 'I am fine' }, { title: 'Mrs. Johnson', body: 'Doing well' } ]; console.log(executeTemplates(template, arrayOfObjects)); // Output: // ['Hello Mr. Smith how are you? I am fine', 'Hello Mrs. Johnson how are you? Doing well']

In this code, for each object in arrayOfObjects, we create a new function that takes the keys of the object as parameters and returns the template string, with the template string embedded in backticks. We then call this function with the values from the object, and this evaluates the template string with the correct values.

Please note that this code executes dynamic JavaScript code, which can expose security risks if the template string contains untrusted input. Always make sure to sanitize and validate any user input before using this approach.

Show me alternative options to that new Function() bit
ChatGPT

Certainly! While using new Function() is a way to create a dynamic function, it does introduce security risks by evaluating arbitrary code. Below are two alternative approaches that you can consider:

1. Manual String Replacement

This approach uses string manipulation to achieve the same goal, without evaluating any code:

javascript
function executeTemplates(template, arrayOfObjects) { return arrayOfObjects.map(obj => { return template.replace(/\$\{(\w+)\}/g, (_, key) => obj[key]); }); } const template = 'Hello ${title} how are you? ${body}'; const arrayOfObjects = [ { title: 'Mr. Smith', body: 'I am fine' }, { title: 'Mrs. Johnson', body: 'Doing well' }, ]; console.log(executeTemplates(template, arrayOfObjects));

2. Using Tagged Template Literals

If you can accept defining the template as a tagged template literal (rather than as a string), you can use the following approach:

javascript
function executeTemplates(template, arrayOfObjects) { return arrayOfObjects.map(obj => { return template(obj); }); } const template = ({ title, body }) => `Hello ${title} how are you? ${body}`; const arrayOfObjects = [ { title: 'Mr. Smith', body: 'I am fine' }, { title: 'Mrs. Johnson', body: 'Doing well' }, ]; console.log(executeTemplates(template, arrayOfObjects));

In this approach, you define the template as a function that takes an object and returns a string using a template literal. Then, you simply call this function with each object in the array.

Note that these alternative options don't use dynamic code evaluation, so they should be more secure than using new Function(). However, they do require the template to be in a slightly different format, depending on the approach you choose.

Continue this conversation
|Terms of use|Privacy policy