CHAPTER 6
Template literals are indicated by enclosing strings in backtick characters and provide syntactic sugar for constructing single and multi-line strings. This is similar to string interpolation features in Perl, Python, and more. Optionally, a tag can be added to allow the string construction to be customized, avoiding injection attacks or constructing higher level data structures from string contents.
The following are some examples of template literals:
Code Listing: 89
`In JavaScript '\n' is a line-feed.` `Now I can do multi-lines with template literals.` |
With string interpolation, we can now compose very powerful strings in a clean, succinct manner. Consider the following example:
Code Listing: 90
var customer = { name: "Matt" }; var product = { name: "Halo 5: Guardians" }; let gift = { timelimit: '4 hours', amount: 50.00 }; let message = `Dear ${customer.name},\n Thank you for making a recent purchase of '${product.name}' on Amazon.com. We would love to get your feedback on your experience. If you respond in the next ${gift.timelimit}, we will give you a gift certificate of $${gift.amount} dollars! We look forward to hearing from you! Best Regards, Amazon Customer Relations`; console.log(message); |
Running the preceding code produces the following output:
Code Listing: 91
Dear Matt, Thank you for making a recent purchase of 'Halo 5: Guardians' on Amazon.com. We would love to get your feedback on your experience. If you respond in the next 4 hours, we will give you a gift certificate of $50 dollars! We look forward to hearing from you! Best Regards, Amazon Customer Relations |
Now that is pretty nice! I can see a lot of cool string interpolation that no longer is constrained to the old string concatenation approach.
Let’s see what else we can do. Consider the following example:
Code Listing: 92
let getTotal = (qty, amount) => { return qty * amount; }; let message = `Shopping cart total: $${getTotal(2, 2.99)}`; console.log(message); |
Running the preceding code produces the following output:
Code Listing: 93
Shopping cart total: $5.98 |
As you can see, we can call functions inside our string interpolation.
You can even do operations inside the string interpolation expression as shown below:
Code Listing: 94
let message = `Shopping cart total: $${2 * 2.99}`; console.log(message); |
Running the preceding code produces the following output:
Code Listing: 95
Shopping cart total: $5.98 |
Perhaps you would like to construct a dynamic URL? This can be accomplished quite easily. Consider the following example:
Code Listing: 96
let credentials = "private-user=admin&private-pw=p@$$w0rd"; let a = "one"; let b = "two"; let url = `http://myapp.com/login?a=${a}&b=${b} Content-Type: application/json X-Credentials: ${credentials} `; console.log(url); let post = `POST ${url}`; |
As you can see, we can use this new feature in quite a lot of different scenarios.
There may come a time that you wish you could create a template literal dynamically, perhaps based on a database call or some other process. This requires more work, but you can support dynamic template literals with a little trickery. Consider the following example:
Code Listing: 97
let processMarkup = (markup, data) => { let fields = markup.match(/{(.+?)}/g); let args = []; let params = []; fields.forEach((field,index,list) => { field = field.replace(/{/g, ''); field = field.replace(/}/g, ''); args.push(data[field]); params.push(field); }); let template = markup.replace(/{/g, '${'); let fn = assemble(template, params); let render = fn.apply(null, args); return render; } let assemble = (template, params) => { return new Function(params, "return `" + template +"`;"); } let markup = `Hello {fname} {lname}, how are you?`; let data = { fname: "Matthew", lname: "Duffield" }; let template = processMarkup(markup, data); console.log(template); |
Here is the output from running the preceding code:
Code Listing: 98
Hello Matthew Duffield, how are you? |
This may not be the most recommended thing to do, but it does show you that you can create dynamic templates. Note that we could not use the same symbols that are used in the string interpolation as that would have been resolved immediately. This is where the Function() constructor comes into play and allows us to “assemble” our template with the new parameters. Again, this is a naïve approach for making dynamic templates, but it does provide a lot of power if you have the need to generate templates on the fly.
As you can see, we can use this new feature in many different ways.