Learning Goals
3 minBy the end of this lesson you will be able to:
- Build a sentence with a template literal and
${ }. - Use
.length,.toUpperCase()and.trim()on text. - Pull part of a string out with
.slice(). - Print a multi-line receipt in the console from one template literal.
Warm-Up · Mind the Gaps
5 minLast lesson you stored values in variables. Here Mei Ling glues some together into a sentence.
const name = 'Mei Ling';
const town = 'Ipoh';
console.log('Hi ' + name + ', welcome to' + town + '!');Predict together
- Exactly what will the console show?
- There is one missing space. Where is it, and which quote marks must change?
Reveal
Hi Mei Ling, welcome toIpoh!The gap is missing after to — it needs ', welcome to ' with a space before the closing quote. Counting spaces inside quote marks is fiddly and easy to get wrong. Today's new tool removes the problem entirely.
New Concept · Text You Can Shape
12 minA string is like a string of beads — one character after another, in order. You can count the beads, look at any one of them, or take a handful from the middle.
Template literals — the tidy way
Instead of single quotes, use backticks (`, usually left of the 1 key). Inside them, any ${ } holds live JavaScript.
const name = 'Mei Ling';
const town = 'Ipoh';
console.log(`Hi ${name}, welcome to ${town}!`);Hi Mei Ling, welcome to Ipoh!The spaces are exactly where you typed them, because you are writing the sentence as a sentence. No plus signs to count.
Joining with +
Easy to lose a space.
Hard to read once there are three or more pieces.
Cannot span lines.
Template literal
You see the finished sentence as you type it.
Any expression fits in ${ } — even sums.
Spans as many lines as you like.
Sums work inside the braces too:
const price = 2.5;
console.log(`Three cost RM ${price * 3}`);Three cost RM 7.5Multi-line text, for free
A template literal keeps your line breaks. This is how you print a receipt without six separate console.log() calls.
const item = 'Roti canai';
console.log(`--- Receipt ---
${item} RM 1.50
Thank you!`);--- Receipt ---
Roti canai RM 1.50
Thank you!Asking a string about itself
Strings carry built-in helpers called methods. You call one by writing a dot, the name, and brackets.
const dish = 'nasi lemak';
console.log(dish.length); // how many characters
console.log(dish.toUpperCase()); // shouty version
console.log(dish.includes('nasi'));10
NASI LEMAK
true.length has no brackets because it is a property — a fact about the string. The others are methods — jobs the string can do.
Taking a slice
Characters are numbered from zero. .slice(start, end) takes from start up to but not including end.
const dish = 'nasi lemak';
console.log(dish.slice(0, 4)); // from 0, stop before 4
console.log(dish.slice(5)); // from 5 to the endnasi
lemakWhy it matters
Every label, heading and message in the React apps you build later is a string built this way. Template literals are the standard — you will see them in almost every professional JavaScript file you ever open.
Worked Example · A Proper Receipt
12 minBuild this in a file called receipt.js, attached to a page as you did in Lesson 1.
Step 1 — The order
// receipt.js — Arjun's order at Warung Aisyah
const customer = 'Arjun';
const dish = 'nasi lemak';
const drink = 'teh tarik';
const dishPrice = 5.5;
const drinkPrice = 2.5;Step 2 — One sentence, one template literal
console.log(`${customer} ordered ${dish} and ${drink}.`);Arjun ordered nasi lemak and teh tarik.Step 3 — Do the maths inside the braces
The total does not need its own variable — the braces can hold the sum:
console.log(`Total: RM ${dishPrice + drinkPrice}`);Total: RM 8Step 4 — The whole receipt at once
Replace all your logs with a single multi-line template literal:
console.log(`
===== WARUNG AISYAH =====
Customer: ${customer.toUpperCase()}
${dish} RM ${dishPrice}
${drink} RM ${drinkPrice}
-------------------------
TOTAL RM ${dishPrice + drinkPrice}
Terima kasih!`);
===== WARUNG AISYAH =====
Customer: ARJUN
nasi lemak RM 5.5
teh tarik RM 2.5
-------------------------
TOTAL RM 8
Terima kasih!What changed? Four separate print statements became one. The layout in your editor is exactly the layout in the console — what you see is what you get.
Step 5 — Tidy up messy input
Real customer names arrive with stray spaces. .trim() removes them from both ends:
const typed = ' priya ';
console.log(`Welcome, ${typed.trim()}!`);
console.log(`Untrimmed length: ${typed.length}`);
console.log(`Trimmed length: ${typed.trim().length}`);Welcome, priya!
Untrimmed length: 11
Trimmed length: 5Notice you can chain methods: .trim() hands back a new string, and .length then measures that.
Try It Yourself
13 minKeep going in receipt.js, or start text.js.
Task 1 — Your own receipt
Copy the Step 4 receipt and change it to your own stall, customer and three items. Every price must appear through a
${ }, never typed straight into the text.Task 2 — A tidy initial
Given a full name, print just the first letter followed by a full stop, then the rest of the name. Start from this shape:
const fullName = 'Nurul Huda'; // goal: N. HudaYou will need
.slice()twice, and possibly.indexOf(' ')to find the space.Task 3 — A shouty banner
Write a banner that prints your stall name in capitals, surrounded by a line of
=signs that is exactly as long as the name.Hint:
'='.repeat(5)gives=====. Combine.repeat()with.lengthso the banner still fits when you change the name.
🔥 Mini-Challenge · The Broken Greeting
8 minHafiz wants a welcome line for his café site. The console prints something strange. Find two mistakes.
// hafiz-welcome.js — buggy
const cafe = 'Kopi Corner';
const town = 'Johor Bahru';
const rating = 4.8;
console.log('Welcome to ${cafe} in ${town}!');
console.log(`Rated ${rating} stars by ${rating.toUpperCase()} reviewers`);It works if: the first line names the café and town, and the second prints the rating with a sensible reviewer count, with no red errors.
Reveal the answer
Mistake 1 — single quotes instead of backticks.
${ } only comes alive inside backticks. In ordinary quotes it is just text, so line 5 prints literally:
Welcome to ${cafe} in ${town}!Mistake 2 — a string method used on a number.
rating is 4.8, a number. Numbers have no .toUpperCase(), so line 6 throws:
TypeError: rating.toUpperCase is not a functionHafiz meant to show a count of reviewers, which should be its own variable.
// hafiz-welcome.js — fixed
const cafe = 'Kopi Corner';
const town = 'Johor Bahru';
const rating = 4.8;
const reviewers = 126;
console.log(`Welcome to ${cafe} in ${town}!`);
console.log(`Rated ${rating} stars by ${reviewers} reviewers`);Welcome to Kopi Corner in Johor Bahru!
Rated 4.8 stars by 126 reviewersThe lesson from mistake 2: methods belong to types. Ask a number to do a string's job and JavaScript stops you.
Recap
3 min- Template literals use backticks and
${ }— spaces land exactly where you type them. - Any expression fits inside the braces, including sums.
- Backtick strings can span several lines, keeping your layout.
.lengthis a property (no brackets);.toUpperCase(),.trim(),.slice()are methods (brackets).- Characters are numbered from 0;
.slice(start, end)stops beforeend. - Methods belong to types — a number has no
.toUpperCase().
New words
- Template literal — a backtick string that can hold
${ }placeholders. - Method — a job a value can do, called with brackets.
- Property — a fact about a value, read without brackets.
- Index — a character's position, counting from 0.
📦 Homework
4 min to brief · ~20 min to doRequired
- Write
ticket.jsthat prints a cinema ticket as one multi-line template literal: film name, cinema in a Malaysian city, seat number, and price in RM. Every changing value must come from a variable. - Bring a screenshot of the console output to next lesson.
Optional stretch
- Use
.padEnd()so all your prices line up in a neat column, however long the item names are. - Find out what
.replace()does and use it to swap one word in your ticket for another.