Exploration of Tagged template Literals
Tags: javascript
Published: 2020-05-24 19:17:55

---
title: "Exploration of Tagged template Literals"
description: "An exploration of tagged template literal with custom interpolation"
canonical_url: "https://cavaleiro.fr/posts/template-literals/"
published: true
tags: javascript, 
---

Hi, this is my first-ever blog post. I'm a French developer around Strasbourg. It's a repost from [my website](https://cavaleiro.fr). Feel free to comment to help me improve my writing and my English (I'm still learning it).

---

Tagged template literal is a powerful feature of JS, standardized with ES2015,
and supported by most browser.

> But, how does it work exactly?

It's a special function where you can add **custom interpolation**.

---

Interpolation example :

- highlight text.
- create custom CSS (see css-in-js solutions).
- interpolate variables from SQL query (more below).

---

And here a custom tagged template function:

```js
function myTaggedTemplate(parts, coolVariable) {
  console.log(parts)
  console.log(coolVariable)
}

myTaggedTemplate`Tagged template are ${"cool"}.`
// => ["Tagged template are ", "."]
// => cool
```

> Great, but how do I do custom interpolation? 😁

Well, ok. I'm going to provide a better example. But before that, a bit more why I ended up with tagged template.

I'm working on a company which build an ERP. We are trying to modernize the core of it and make the modernization of it as simple as possible
for other employee.

In that research, we ended wanting to have a small wrapper around SQL because most employee who use our tools known SQL well
but not JS.

---

_Merge query with user input is not a good idea to avoid **SQL injection**._

---

This is why we end up with tagged template. Tagged template isolate user input by default. **And this is a wonderful feature**.

The other interesting part : SQL driver already sanitize input for SQL command.
Since tagged template separate query from input, _the work is done._

Here how it looks :

```js
const { query, variables } = query`
  SELECT desc, unit, price
  from sales
  where status = ${"completed"} and customer_id = ${15735}
  order by created_at desc
`
// query => select desc, unit, price from sales where status = :0 order by created_at desc
// variables => ["completed", 15735]
```

_`completed` and `15735` are inline here but that data came from user input._

And how it works :

```js
// we use `...variables` because we don't know how many `${}` developers are going to use.

function query(parts, ...variables) {
  let query = ""
  // we need to concatenate the string parts.
  for (let i = 0, size = parts.length; i < size; i++) {
    query += parts[i]
    // if we have a variables for it, we need to bind it.
    if (variables[i]) {
      query += ":" + i
    }
  }

  return { query, variables }
}
```

The function split query from variables by default. And then, we can leverage on the SQL driver to make a safe query and avoid SQL injection.

---

  The example right here is because I use `oracle` as a database at work. Other
  drivers my expect something else then `:0`, `:1`, and so on.

---

Same example with execute from `oracledb`

```js
const { query, variables } = query`
  SELECT desc, unit, price
  from sales
  where status = ${"completed"} and customer_id = ${15735}
  order by created_at desc
`
// connection object from oracledb
const result = await connection.execute(query, variables)
```

Pretty cool, uh?