arrow cursor
< javascript tutorials

ES6 Tagged Template Literals Example | Tweet It | CSS Visual Dictionary

Written by @js_tut (Twitter)

In this tutorial we'll take a look at tagged template literals.

You may already know that ES6 introduced creation of Template Literals by using the `` quotes (instead of single or double quotes, which will not work with Template Literal ${A} syntax.)

    let A = 1;
    let TL = `Hello there, include variable ${A} in text.`; // Hello there, include variable 1 in text.

But it's possible to combine Template Literals with a custom-written function, created specifically to work with Template Literals. Hence, this is where the concept of Tagged Template Literal concept comes from.

The "tag" is the function name that precedes the Template Literal. Here are a few examples:

    let A = 1;
    let age = 7;

    F`${A}`;                               // Returns anything you want
    catage`Your cat is ${age} years old.`; // Returns anything you want
    dog`Your dog has ${4} legs.`;          // Returns anything you want

The functions F, catage and dog are your standard JavaScript functions.

The return value of such a function can actually be anything you want. The rest of this tutorial will walk you through how to create a function that converts the original TL string into a more sophisticated return value.

This syntax may appear puzzling at first, especially to pre-ES6 coders. Never before had we executed a function without using parenthesis (). And never before had we passed arguments to it via Template Literals. Certainly, never before had we returned the value that rewrote the string completely with our own output, that had nothing to do with the Template Literal that was used:

    function A() { return 'Rewritten.'; }

    A`Hello there.`; // "Rewritten."

So, whatever the tagged function returns will be the replacement of the actual Template Literal provided. In this case `Hello there.` will be rewritten to `Rewritten.`. You can pass the original string back to the return value. But there is a catch. You can't simply take it and pass it back as a return value. Because this type of a function breaks down the TL into parts separated by strings and TLs nested in it.

The key is writing the function body that actually accomplishes something useful. What it is, is entirely up to you and what you're trying to accomplish. In this basic example we'll explore how to create a tagged function for using together with template literals.

Such a function is best defined by two arguments: strings and ...values (using the ... rest "operator.")

// Let's create a function F, as a special function to be used to *rewrite Template Literals
function F(strings, ...values) {

    let result = ``;
    
    // Receive **parts of the Template Literal in "strings" and iterate over them
    strings.map((value, index) => {

        // Note: "...values" will hold ${A}, ${B}, and ${C} (see the code below this function)
        // or list of values enumerating all Template Literals (${A}, ${B}, ...) from the TL string

        // Get TL number at current index, but avoid last one, which will always be 'undefined'
        let number = (index <= values.length - 1) ? values[index] : ``;

        // Rewrite digits to strings -- this is one of the benefits of using
        // Template Literal-based functions. That is... reformatting the input.
        number == 1 ? number = "One" : null;
        number == 2 ? number = "Two" : null;
        number == 3 ? number = "Three" : null;

        // Combine string and numbers and add to the tail of the running string
        result += value + number;
    });

    return result;
}

This function will make a lot more sense in a moment. But basically all it does is rewrite variables (see below) A, B and C into strings "One", "Two", and "Three". Internally inside the function it is accomplished by iterating strings values (using .map method) and re-combining them with ...values

    // Let's create some variables
    let A = 1;
    let B = 2;
    let C = 3;

Putting Template Literal (`Hello ${A} and ${B}`, for example) *after function name (F, in this case) will trigger the function call, just like F(), or F.call() would.

The difference is that ${A}, ${B}, and ${C} are passed as "...values" (see function F definition above) and the ... dots are the "rest" operator. It grabs all of the Template Literals, not just 1.

Our setup is ready, let's call the tagged template literal function F and see what happens:

    F`Numbers are ${A}, ${B} and ${C}.`; // "Numbers are One, Two and Three."

The syntax above where you have F (name of the function) right before a Template Literal will execute that function and pass the Template Literal values to the function as arguments.

I am sure more advanced use-cases are possible. But this is at the very basic, how Tagged Template Literals work in JavaScript.

How To Create an Interactive Flex Layout Designer In JavaScript | Tweet It | CSS Visual Dictionary