What exactly is JavaScript Tagged Template Literal?
Tags: javascript, beginners, webdev, codenewbie
Published: 2020-10-13 06:09:59

Before ES6(ECMAScript 2015), we have used single quotes('...') and double quotes("...") to wrap string literals. A simple example is,

```js
var msg = "Hello, I'm Joe and my favorite color is purple";
```
There were limitations when we had to concatenate multiple strings and the string literal has dynamic values. The readability of these concatenations used to be a challenge as well.

```js
var frag1 = "Hello, I'm";
var val1= "Joe";
var frag2 = "and my favorite color is";
var val2 = "purple";

var msg = frag1 + ' ' + val1 + ' ' + frag2 + ' ' + val2;
```
Do you see another problem? If someone only reading the line where the concatenation takes place, he/she doesn't have much idea of the resultant string.

With ES6 we have got `template literals` which are string literals that allow embedding expressions. Template literals are enclosed by the backtick ``(` `)`` characters instead of single or double-quotes.

`Template literals` can contain placeholders that are specified by the dollar sign(`$`) and curly braces(`${expression}`). The above example can be written with template literals as,

```js
const name = 'Joe';
const color = 'purple';

const message = `Hello, I'm ${name} and my favorite color is ${color}`;
console.log(message);
```
Output,

```shell
Hello, I'm Joe and my favorite color is purple
```
This is much better and favorable for developers to use.

# What is the Tagged Template Literal?

A `Tagged Template Literal` is usually a function that precedes a `template literal` to help you in manipulating the output. It's fine if you find it confusing. We will understand it in a few simple steps.

Let us take an example of this template literal again,

```js
`Hello, I'm ${name} and my favorite color is ${color}`
```
We want to manipulate the output such that, it returns a string like the below when we pass the name as, `Joe` and color as, `green`.

```shell
Hello Joe, Have a Nice Day! We know your favorite color is green
``` 
How about, displaying this message in the color that is passed as an expression to the template literal? Like this when the color value is `green`,

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1602501448782/wZsUF3_cW.png?border=1,CCCCCC&auto=compress)

## Welcome Tag function
Let us first create a `tag` function. This is a regular JavaScript function that should return a value as per your needs. This return value is usually a manipulated output based on the template literal strings and expressions.

```js
function introduce() {                
    return 'introduce...';
}
```
Next, We mention the `tag` function before the template literal so that, the tag function gets associated with it.

```js
const name = 'Joe';
const color = 'green';

const message = introduce`Hello, I'm ${name} and my favorite color is ${color}`;
```
Please note the tag function `introduce` before the template literal.

## Tag function takes arguments
The first argument of a `tag function` contains an array of string values. The remaining arguments are related to the expressions.

```js
function introduce(strings, arg0, arg1) {
  console.log('strings', strings);
  console.log('arg0', arg0);
  console.log('arg1', arg1);
                    
  return 'introduce...';
}

const name = 'Joe';
const color = 'purple';

const message = introduce`Hello, I'm ${name} and ${color} is my favorite color!`;
```

The argument `strings` is an array of all the strings in the template literals and both `arg0` and `arg1` represent the `name` and `color` values here.

![split_1.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1602488318771/0BZCElbkV.png?border=1,CCCCCC&auto=compress)

Output,

![screen_1.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1602488309138/DD_HX82V-.png?border=1,CCCCCC&auto=compress)

Passing the expressions as individual arguments is not so great. Think about it, if there are 10 expressions in a template literal. We can make use of `JavaScript rest operator(...values)` to collect the arguments as an array.

```js
function introduce(strings, ...values) {
  console.log('strings', strings);
  console.log('values', values);
                                                           
  return 'introduce...';
}

const name = 'Joe';
const color = 'purple';

const message = introduce`Hello, I'm ${name} and ${color} is my favorite color!`;
```
In this case, both `strings` and `values` are arrays. The `strings` argument contains all the strings where the `values` argument contains all the expression values.

![split_2.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1602488341281/yCYbybRCj.png?border=1,CCCCCC&auto=compress)

Output,

![screen_2.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1602488330479/5ATrgemq8.png?border=1,CCCCCC&auto=compress)

Now, we can do everything possible with these strings and expression values to manipulate them.

## The desired output
To get the desired output after the string manipulation, we will write a small logic inside the `introduce` function.

```js
 function introduce(strings, ...values) {                                                        
   let msg = 
     `<span style="color:${values[1]}">
           Hello ${values[0]}, Have a Nice Day! We know your favorite color is <u>${values[1]}</u>
      </span>`;
                    
   return msg;
}

const name = 'Joe';
const color = 'green';

const message = introduce`Hello, I'm ${name} and ${color} is my favorite color!`;

console.log(message);

```
We create a new template literal using the expression values and wrap it with the `span` element. Please notice, we have added a style to the span element to color the text as well.

Output,

```html
<span style="color:green">
    Hello Joe, Have a Nice Day! We know your favorite color is <u>green</u>
</span>
```
Now, if you use the above output to add as `innerHTML` you can render it in the browser.

```js
document.body.innerHTML = message;
```
Output,

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1602501448782/wZsUF3_cW.png?border=1,CCCCCC&auto=compress)

The text color will change as and when you change the color variable value in your code.

# Did you know 💅?

If you are familiar with [reactjs](https://reactjs.org/), you probably know about the [styled-component](https://styled-components.com/). But, did you know, `styled-components` are created using `tagged template literals`? 

Yes true. Notice the syntax of a button created with the styled-component,

```js
const Button = styled.button`
  background-color: papayawhip;
  border-radius: 3px;
  color: palevioletred;
`
```
Does it look familiar to the tagged template literal we learned? Read this awesome article [The magic behind 💅 styled-components](https://mxstbr.blog/2016/11/styled-components-magic-explained/) to know more about it.

# Conclusion
`Tagged Template Literals` are powerful and the usage will vary from one application to another. If you are using it already, please let us know in the comment section below.

At the same time, if you were new to it before reading the article, lookout for opportunities to use it.

I have updated the `js-tips-tricks` project in GitHub with code examples. You may want to have a look.

{% github atapas/js-tips-tricks %}

You may also like,
- [My Favorite JavaScript Tips and Tricks](https://blog.greenroots.info/my-favorite-javascript-tips-and-tricks-ckd60i4cq011em8s16uobcelc)
- [Explain Me Like I am Five: What are ES6 Symbols?](https://blog.greenroots.info/explain-me-like-i-am-five-what-are-es6-symbols-ckeuz5sb8001qafs14of305dw)
- [How to use JavaScript Collection with Map](https://blog.greenroots.info/how-to-use-javascript-collection-with-map-ckfc477g005sy22s1fra3akvo)
- [Everything you need to know about JavaScript Set](https://blog.greenroots.info/everything-you-need-to-know-about-javascript-set-ckfgkprkg01pw8as1epsycua8)
- [JavaScript: Equality comparison with ==, === and Object.is](https://blog.greenroots.info/javascript-equality-comparison-with-and-objectis-ckdpt2ryk01vel9s186ft8cwl)

<hr />
If it was useful to you, please Like/Share so that, it reaches others as well. You can @ me on Twitter ([@tapasadhikary](https://twitter.com/home)) with comments, or feel free to follow me.