<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Julien Cavaleiro</title>
    <description>The latest articles on DEV Community by Julien Cavaleiro (@juliencavaleiro).</description>
    <link>https://dev.to/juliencavaleiro</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F184454%2F380c6081-fb16-414c-a06a-0902bb5e9232.jpg</url>
      <title>DEV Community: Julien Cavaleiro</title>
      <link>https://dev.to/juliencavaleiro</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/juliencavaleiro"/>
    <language>en</language>
    <item>
      <title>Exploration of Tagged template Literals</title>
      <dc:creator>Julien Cavaleiro</dc:creator>
      <pubDate>Sun, 24 May 2020 19:17:55 +0000</pubDate>
      <link>https://dev.to/juliencavaleiro/exploration-of-tagged-template-literals-2jkl</link>
      <guid>https://dev.to/juliencavaleiro/exploration-of-tagged-template-literals-2jkl</guid>
      <description>&lt;p&gt;Hi, this is my first-ever blog post. I'm a French developer around Strasbourg. It's a repost from &lt;a href="https://cavaleiro.fr"&gt;my website&lt;/a&gt;. Feel free to comment to help me improve my writing and my English (I'm still learning it).&lt;/p&gt;




&lt;p&gt;Tagged template literal is a powerful feature of JS, standardized with ES2015,&lt;br&gt;
and supported by most browser.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;But, how does it work exactly?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It's a special function where you can add &lt;strong&gt;custom interpolation&lt;/strong&gt;.&lt;/p&gt;



&lt;p&gt;Interpolation example :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;highlight text.&lt;/li&gt;
&lt;li&gt;create custom CSS (see css-in-js solutions).&lt;/li&gt;
&lt;li&gt;interpolate variables from SQL query (more below).&lt;/li&gt;
&lt;/ul&gt;



&lt;p&gt;And here a custom tagged template function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;myTaggedTemplate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;coolVariable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;coolVariable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;myTaggedTemplate&lt;/span&gt;&lt;span class="s2"&gt;`Tagged template are &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cool&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.`&lt;/span&gt;
&lt;span class="c1"&gt;// =&amp;gt; ["Tagged template are ", "."]&lt;/span&gt;
&lt;span class="c1"&gt;// =&amp;gt; cool&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Great, but how do I do custom interpolation? 😁&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;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&lt;br&gt;
for other employee.&lt;/p&gt;

&lt;p&gt;In that research, we ended wanting to have a small wrapper around SQL because most employee who use our tools known SQL well&lt;br&gt;
but not JS.&lt;/p&gt;



&lt;p&gt;&lt;em&gt;Merge query with user input is not a good idea to avoid &lt;strong&gt;SQL injection&lt;/strong&gt;.&lt;/em&gt;&lt;/p&gt;



&lt;p&gt;This is why we end up with tagged template. Tagged template isolate user input by default. &lt;strong&gt;And this is a wonderful feature&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The other interesting part : SQL driver already sanitize input for SQL command.&lt;br&gt;
Since tagged template separate query from input, &lt;em&gt;the work is done.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Here how it looks :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;variables&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="s2"&gt;`
  SELECT desc, unit, price
  from sales
  where status = &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;completed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; and customer_id = &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="mi"&gt;15735&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
  order by created_at desc
`&lt;/span&gt;
&lt;span class="c1"&gt;// query =&amp;gt; select desc, unit, price from sales where status = :0 order by created_at desc&lt;/span&gt;
&lt;span class="c1"&gt;// variables =&amp;gt; ["completed", 15735]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;em&gt;&lt;code&gt;completed&lt;/code&gt; and &lt;code&gt;15735&lt;/code&gt; are inline here but that data came from user input.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;And how it works :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// we use `...variables` because we don't know how many `${}` developers are going to use.&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;
  &lt;span class="c1"&gt;// we need to concatenate the string parts.&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="c1"&gt;// if we have a variables for it, we need to bind it.&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;variables&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;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.&lt;/p&gt;




&lt;p&gt;The example right here is because I use &lt;code&gt;oracle&lt;/code&gt; as a database at work. Other&lt;br&gt;
  drivers my expect something else then &lt;code&gt;:0&lt;/code&gt;, &lt;code&gt;:1&lt;/code&gt;, and so on.&lt;/p&gt;



&lt;p&gt;Same example with execute from &lt;code&gt;oracledb&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;variables&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="s2"&gt;`
  SELECT desc, unit, price
  from sales
  where status = &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;completed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; and customer_id = &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="mi"&gt;15735&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
  order by created_at desc
`&lt;/span&gt;
&lt;span class="c1"&gt;// connection object from oracledb&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Pretty cool, uh?&lt;/p&gt;

</description>
      <category>javascript</category>
    </item>
  </channel>
</rss>
