loading...
Cover image for A simple thing I learned during a code review: Tagged templates

A simple thing I learned during a code review: Tagged templates

dvddpl profile image Davide de Paolis ・4 min read

The other day I was reviewing some code and I found myself staring puzzled at this snippet:

fixture `A bunch of tests`
    .page `http://myapp.github.io/example`;

Of course I noticed the template literals and I was sure that it was a function being passed a parameter and then returning a fluent interface, but I really could not make sense of the syntax. To did not resemble valid JS script code to me.

what is that

I checked the documentation of the test framework being used to automate end to end tests on the UI. (In the past we just used Puppeteer for some really basic stuff, in some projects we tried out Cypress.io, for this project the team/developer went for TestCafeΒ΄. So this test framework was new to me. )

Everything looked as it should:

// To declare a test fixture, use the fixture function.
fixture( fixtureName )
fixture `fixtureName`

So.. what was the magic allowing that syntax?
I donΒ΄t remember what exactly I typed in google but was something like javascript template literals as methods and of course the first result was enough to illuminate me with such a trivial thing:

Tagged Templates

So far I always used Template Literals for their very basic and very useful features :

String Interpolation

that means being able to write :

console.log(`Hi ${name}! Today is ${new Date().toString()}.`)

instead of

console.log('Hi ' + (name) + '! Today is ' + new Date().toString() +'.');

Multiline Strings

that allows you to write multiline text without having to append plus and new line for each row.
Forget about this:

const twinkle = "Twinkle, twinkle, little star\n"+
"How I wonder what you are\n"+
"Up above the world so high\n"+
"Like a diamond in the sky\n"+
"Twinkle, twinkle little star\n"+
"How I wonder what you are"

meet this:

const twinkle = `Twinkle, twinkle, little star
How I wonder what you are
Up above the world so high
Like a diamond in the sky
Twinkle, twinkle little star
How I wonder what you are`

Honestly, I never really took the time to read the entire the documentation of Template Literals and I too many times stopped reading the documentation exactly at the Tagged Templates... :

Tags allow you to parse template literals with a function. The first argument of a tag function contains an array of string values. The remaining arguments are related to the expressions.

Never really made immediate sense to me and could not imagine a real-world scenario.

This time I tried to understand why you would use the Tagged template when writing that test use case.

I tried to rewrite the example in the documentation

function myTag(strings, personExp, ageExp) {
  var str0 = strings[0]; // "That "
  var str1 = strings[1]; // " is a "

  // There is technically a string after
  // the final expression (in our example),
  // but it is empty (""), so disregard.
  // var str2 = strings[2];

  var ageStr;
  if (ageExp > 99){
    ageStr = 'centenarian';
  } else {
    ageStr = 'youngster';
  }

  // We can even return a string built using a template literal
  return `${str0}${personExp}${str1}${ageStr}`;
}
var person = 'Mike';
var age = 28;

console.log(myTag`That ${ person } is a ${ age }`)
 // "That Mike is a youngster"

Ok, Here we are passing a string containing some replacements, and the function applies internally some conditional logic before printing/concatenating that string.
How would that method be invoked normally, without the syntactic of template literals?

When I tried with

console.log(myTag("That " + person + " is a " + age ))

I got

Tundefinedhyoungster

while with

console.log(myTag("That ", person, " is a ", age ))

the output was

TMikehyoungster

Ok, let's read again the docs

The first argument of a tag function contains an array of string values.

The remaining arguments are related to the expressions

That means that in order to achieve the same result you would have to invoke it like this:

console.log(myTag(["That ", " is a "], person, age ))

Well, like this it makes perfect sense. And Tagged functions immediately appear very practical!

aha moment

Furthermore, tagged functions donΒ΄t have to return necessarily a string, but it can be anything. Like in the example, the variables/replacements can be used for handle some manipulation and conditional logic before returning the formatted string and probably in the test framework source code, the string is saved internally and the TestSuite instance is returned as fluent Interface.

Even though if this was something simple, I am very happy that I discovered something new while reviewing some code written by a less experienced colleague.
Too many experienced developers take code reviews as an opportunity to be picky, overly critical and patronizing, but that should never be so.

Never miss a chance to learn something.
Never underestimate the learnings you can get from Code Reviews.

Always take a little bit of extra time to dig deeper into something that you don't know, don't' understand and tickles your curiosity.

Did you have some Aha Moments while reviewing some other people code?


Cover image by Sergi Viladesau on Unsplash

Posted on by:

dvddpl profile

Davide de Paolis

@dvddpl

Sport addicted, productivity obsessed, avid learner, travel enthusiast, expat, 2 kids. πŸ‚βœˆπŸšžπŸŒπŸ“·πŸ–₯πŸ€˜πŸ‘¨β€πŸ‘©β€πŸ‘¦β€πŸ‘¦πŸš€ (Opinions are my own)

Discussion

markdown guide
 

This is my major arguement, when it comes to the question why code reviews are important.
There are always at least two people who learn from each other.
And even if you are an experienced dev, there are still things you haven't seen or learned.

Thumbs up!

 

Never knew this use case existed.

Thanks for sharing!