/ javascript

Benefits of JavaScript Template Literals and Tagged Templates


String formation from variables in JavaScript had been pain all the time. No more, JavaScript Template Literals and Tagged Templates will save a lot of your time. Let's see working and benefits of JavaScript Template Literals and Tagged Templates.

JavaScript Template literals

JavaScript Template literals are the Literals or Strings allowing Expression in between them. These are enclosed inside two backticks(`) and the expressions start with $ sign and then are enclosed in curly braces {}. And the output of expression is placed at that position where the expression is embeded. For example:

let name = '';
console.log(`Hello ${name}!`);

name = 'World';
console.log(`Hello ${name}!`);

name = 'Pankaj';
console.log(`Hello ${name}!`);

generating the output like:

Hello !
Hello World!
Hello Pankaj!

So the template literal Hello ${name}! is equal to 'Hello ' + name + '!'.

That was the trivial usage of Template Literals. Going forward on advanced usage, the expressions can be anything which may return a String. If not convertible to String, then it will try to convert it to string and may give output like [object Object].

For example if you give { place: 'World', name: 'Pankaj'] } to the name variable above, you will get Hello [object Object]!

And the strings can have newlines and any character in between. Following is a valid example of Template Literal. On usage, this will preserve the spaces and tabs in the output as well.

const template = (name, profileUrl, pictureUrl) => `
<div>
  <p><a href="${profileUrl}">${name}</a></p>
  <img src="${pictureUrl}" style="max-height: 200px" />
</div>
`
template('Pankaj', '//pankaj.pro', 'https://avatars0.githubusercontent.com/u/251937?s=200&v=4');

Which on executing will give following output:

"
<div>
  <p><a href="//pankaj.pro">Pankaj</a></p>
  <img src="https://avatars0.githubusercontent.com/u/251937?s=200&v=4" />
</div>
"

which now can be used in any way, like following:

let div = document.createElement('div');
div.id = 'profile';
div.innerHTML = template('Pankaj', '//pankaj.pro', 'https://avatars0.githubusercontent.com/u/251937?s=200&v=4');
div.setAttribute('style', 'display: block; width: 200px; height: 200px;');
document.body.appendChild(div);

Now lets see how to render a list of links for navigation menu. Example markup is from Nav in Bootstrap 4.

const topLevel = [
  { label: 'Home', url: '/home' },
  { label: 'Products', url: '/products' },
  { label: 'Services', url: '/services' },
  { label: 'About', url: '/about-us' },
  { label: 'Contact', url: '/contact-us' },
];

const social = [
  { label: '<i class="fa fa-facebook-square"></i>', url: 'https://facebook.com/time2hack' },
  { label: '<i class="fa fa-twitter-square"></i>', url: 'https://twitter.com/time2hack' },
  { label: '<i class="fa fa-google-plus-square"></i>', url: 'https://plus.google.com/+Time2hack' },
]

const menu = (menuData) => `
<ul class="nav">
  ${menuData.map(item => `
    <li class="nav-item">
      <a class="nav-link" href="${item.url}">${item.label}</a>
    </li>
  `)}
</ul>
`;

And considering that we have these menus on header and footer, on executing the above code in following way; we will add it to page.

document.querySelector('body > header').innerHTML += menu(topLevel);
document.querySelector('body > footer').innerHTML += menu(social);

Tagged Templates

Tagged Templatesd are the template literals which are tagged some another function for further processing.

For example:

const tag = (parts, name, url) => {
    return `${parts[0]}__${name}__${parts[1]}__${url}__`;
}

const name = 'Pankaj';
const url = 'http://pankaj.pro';

console.log(tag`I am ${name} and you can reach me at ${url}`);

which will give following output:

I am __Pankaj__ and you can reach me at __http://pankaj.pro__

The expressions reaching as the parameters to the tagging function are already executed and hence you can do more of the text processing of the template parts.

With tagged templates, you can achieve more wide range of the templates' capabilities.

Let's take following example of unknown number of expressions and wrap all the expression parameters with code html tag:

const tag = (parts, ...params) => {
	const strParts = parts.slice();
	const exprParts = params.slice();
    const output = [];
    while(strParts.length) {
        output.push(strParts.shift());
        exprParts.length && output.push(`<code>${exprParts.shift()}</code>`);
    }
    return output.join('');
}

const name = 'Pankaj';
const url = 'http://pankaj.pro';

console.log(tag`I am ${name} and you can reach me at ${url}`);

which will generate the following output:

I am <code>Pankaj</code> and you can reach me at <code>http://pankaj.pro</code>

And with such power to JavaScript Template Literals we can easily remove the need of template engine if our needs/requirements are not too wide-range for templates.

Please let un know about your experiences and any problems you are facing with Template Literals in comments; we will try our best to help you.

If you like the article, please share with others so that it reaches to many and can help them.