There and Back Again: A Tale of X-Men, Template Literals, & Learning By “Roundabouting”

In most pursuits, discovering that there was a shorter approach to a task after completing said task usually begets frustration and regret. If I drove all the way from Seattle to Portland to get my favorite order from Dutch Bros., I would be irked if, upon my return, I discovered there was a Dutch Bros. location in Everett, WA; a 6-hour roundtrip across states versus a 90-minute jaunt? I wouldn’t even be able to enjoy my coconut mocha.

With computer programming, however, the roundabout way of accomplishing something doesn’t necessarily elicit this kind of sentiment. Sure, smart programmers SHOULD do their research to find opportunities where they don’t have to reinvent the wheel, but accidentally taking a longer route to accomplish a task has its benefits. Not only does it foster an appreciation for those who came before us whose syntax / packages we can repurpose and make our lives easier, but taking “the long way round” can solidify your understanding of programming fundamentals as you grow in your coding capabilities.

The below scenario epitomizes this concept, as I tasked myself with creating an acceptance letter to Xavier’s School for Gifted Youngsters using JavaScript through console logging. What started as an exercise in practicing string interpolation ended up being a critical lesson in the power of template literals (dash notation). Because, even beyond vanilla JavaScript, template literals are what?

Here’s a walkthrough of my initial approach:

Okay, so let’s start with the basics. I know I want to interpolate a handful of bindings that correspond to the types of values one would expect on any type of acceptance letter, let alone one for the X-Men.

const firstName = "Kurt";
const lastName = "Wagner";
const mutantName = "Nightcrawler";
const placeOfOrigin = "Germany";
const mutantPower = "Teleportation"
const whenPowersManifested = "1975";
const letterSender = "Professor Charles Xavier";
console.log(mutantName);//=> Nightcrawler

Cool, so let’s put our bindings aside for now, and simply write up our acceptance letter verbatim and assign it to a variable named [acceptanceLetter].

let acceptanceLetter ="Dear Kurt Wagner,Congratulations! I am pleased to notify you that you have been granted admission to Xavier's School for Gifted Youngsters to pursue full-time study for the 1975 academic year.Our haven for mutantkind recently detected a large spike in mutant activity in Germany and learned of your recent heroic efforts under the moniker Nightcrawler.I very much hope that you will decide to join us in the Fall. We know that your Teleportation power can prove to be a valuable asset to both human and mutantkind.Sincerely,Professor Charles Xavier";

So we know we’re going to have an issue with the above string: When Javascript encounters punctuation within my double quotes (comma’s and apostrophe’s and whatnot), it’s going to be a smartypants and think I’m trying to do something tricky, versus having those elements explicitly represent what they are in the letter. Enter the escape character ( \ ), which will essentially tell JavaScript, “Hey, if you see punctuation after the \, just treat it like it’s actual punctuation in the string.”

let acceptanceLetter = "Dear Kurt Wagner\, Congratulations! I am pleased to notify you that you have been granted admission to Xavier\'s School for Gifted Youngsters to pursue full-time study for the 1975 academic year. Our haven for mutantkind recently detected a large spike in mutant activity in Germany and learned of your recent heroic efforts under the moniker Nightcrawler. I very much hope that you will decide to join us in the Fall. We know that your Teleportation power can prove to be a valuable asset to both human and mutantkind. Sincerely\, Professor Charles Xavier";console.log(acceptanceLetter);//=> Dear Kurt Wagner, Congratulations! I am pleased to notify you that you have been granted admission to Xavier's School for Gifted Youngsters to pursue full-time study for the 1975 academic year. Our haven for mutantkind recently detected a large spike in mutant activity in Germany and learned of your recent heroic efforts under the moniker Nightcrawler. I very much hope that you will decide to join us in the Fall. We know that your Teleportation power can prove to be a valuable asset to both human and mutantkind. Sincerely, Professor Charles Xavier

Hmm, so it looks like, based on the return results of the above string, that JavaScript is ignoring my elegant spacing between paragraphs and throwing my letter into one huge chunk. We’ll address this in step five, but for now, let’s switch out our placeholder values in the letter with interpolated bindings (and switch out our double quotes ( “ ) to dashes ( ` ) so interpolation actually works!)

let acceptanceLetter = `Dear ${firstName} ${lastName}\, Congratulations! I am pleased to notify you that you have been granted admission to Xavier\'s School for Gifted Youngsters to pursue full-time study for the ${whenPowersManifested} academic year. Our haven for mutantkind recently detected a large spike in mutant activity in ${placeOfOrigin} and learned of your recent heroic efforts under the moniker ${mutantName}. I very much hope that you will decide to join us in the Fall. We know that your ${mutantPower} power can prove to be a valuable asset to both human and mutantkind. Sincerely\, ${letterSender}`;

Okay, NOW let’s get our letter to be broken out as I initially typed it instead of in a huge chunk o’ text. Maybe we could tackle this by declaring each line of the acceptance letter as its own variable, then adding all those variables to an array!

let acceptanceLetterLine1 = `Dear ${firstName} ${lastName}`;
let acceptanceLetterLine2 = `Congratulations! I am pleased to notify you that you have been granted admission toXavier's School for Gifted Youngsters to pursue full-time study for the ${whenPowersManifested} academic year.`;
let acceptanceLetterLine3 = `Our haven for mutantkind recently detected a large spike in mutant activity in ${placeOfOrigin} and learned of your recent heroic efforts under the moniker ${mutantName}.`;
let acceptanceLetterLine4 = `I very much hope that you will decide to join us in the Fall. We know that your ${mutantPower} power can prove to be a valuable asset to both human and mutantkind.`
let acceptanceLetterLine5 = `Sincerely,`
let acceptanceLetterLine6 = `${letterSender}`
let acceptanceLetter = [
acceptanceLetterLine1,
acceptanceLetterLine2,
acceptanceLetterLine3,
acceptanceLetterLine4,
acceptanceLetterLine5,
acceptanceLetterLine6
]
console.log(acceptanceLetter);//=> [
'Dear Kurt Wagner',
"Congratulations! I am pleased to notify you that you have been granted admission toXavier's School for Gifted Youngsters to pursue full-time study for the 1975 academic year.",
'Our haven for mutantkind recently detected a large spike in mutant activity in Germany and learned of your recent heroic efforts under the moniker Nightcrawler.',
'I very much hope that you will decide to join us in the Fall. We know that your Teleportation power can prove to be a valuable asset to both human and mutantkind.',
'Sincerely,',
'Professor Charles Xavier'
]

This is looking MUCH closer to what we want! Still a little choppy visually, but at least lines are separated out as desired.

So the above console log returned the entire acceptanceLetter array we built, but what we REALLY want to happen is for JavaScript to provide a console log for each line within the array. Yep, you guessed it, we’re going to iterate over our array. Hmm, maybe if I throw an empty string (“”) between paragraphs as elements in the array, that will also give me the line spacing I want too!

let acceptanceLetterLine1 = `Dear ${firstName} ${lastName},`;
let acceptanceLetterLine2 = `Congratulations! I am pleased to notify you that you have been granted admission toXavier's School for Gifted Youngsters to pursue full-time study for the ${whenPowersManifested} academic year.`;
let acceptanceLetterLine3 = `Our haven for mutantkind recently detected a large spike in mutant activity in ${placeOfOrigin} and learned of your recent heroic efforts under the moniker ${mutantName}.`;
let acceptanceLetterLine4 = `I very much hope that you will decide to join us in the Fall. We know that your ${mutantPower} power can prove to be a valuable asset to both human and mutantkind.`l
let acceptanceLetterLine5 = `Sincerely,`;
let acceptanceLetterLine6 = `${letterSender}`;
let acceptanceLetter = [acceptanceLetterLine1, "", acceptanceLetterLine2, "", acceptanceLetterLine3, "", acceptanceLetterLine4, "", acceptanceLetterLine5, acceptanceLetterLine6];acceptanceLetter.forEach(line => console.log(line));//=> Dear Kurt Wagner,Congratulations! I am pleased to notify you that you have been granted admission toXavier's School for Gifted Youngsters to pursue full-time study for the 1975 academic year.Our haven for mutantkind recently detected a large spike in mutant activity in Germany and learned of your recent heroic efforts under the moniker Nightcrawler.I very much hope that you will decide to join us in the Fall. We know that your Teleportation power can prove to be a valuable asset to both human and mutantkind.Sincerely,
Professor Charles Xavier

VOILA! We have what we wanted. All it took was some trial and error, string interpolation, parsing our message into separate lines, adding those to an array, and iterating through that array. It was only after building all this that I asked myself, “Hmm, wonder what happens if I just throw the whole darn thing between template literals.”

let acceptanceLetter =`Dear ${firstName} ${lastName},Congratulations! I am pleased to notify you that you have been granted admission to Xavier's School for Gifted Youngsters to pursue full-time study for the ${whenPowersManifested} academic year.Our haven for mutantkind recently detected a large spike in mutant activity in ${placeOfOrigin} and learned of your recent heroic efforts under the moniker ${mutantName}.I very much hope that you will decide to join us in the Fall. We know that your ${mutantPower} power can prove to be a valuable asset to both human and mutantkind.Sincerely,
${letterSender}`;
console.log(acceptanceLetter);

Yes, you guessed it. After all that work, I finally discovered how powerful and wonderful template literals can be; sure, they enable string interpolation, but they also take literally everything you put between them at face value. Truly, this is what puts the “literal” in template literal.

Make no mistake: This “roundabouting” happens. A lot. And that’s a good thing! Because, unsurprisingly, I will now never forget a) the power of template literals b) the importance of doing your research on even the most fundamental of concepts and c) because I had a heck of a good time sleuthing through both solutions. In fact, this methodology, whether intentional or not, has become cardinal in this fledging stage of my time as a developer. Here are a few other examples of this approach coming to light:

  • Console logging every single element in an array / object through bracket / dot notation and THEN learning about iterators.
  • Building a function that transforms every element in an array to another value, and THEN learning about JavaScript’s .map() method.
  • Leveraging vanilla JavaScript to get comfortable with manipulating / adding elements to the DOM through imperative means and THEN getting introduced to React and the wonders of declarative programming.

The takeaway: Concept is king, especially when concepts build upon other concepts as they typically do in software engineering. Don’t ever beat yourself up for realizing there was a better / faster / simpler way after the fact, and be proud you got to the destination no matter the journey you took.