Warm-up · Activity 1 of 7
// B2.3 · ~30 min · Beginner
Strings and template literals
After this lesson you can write any text as a JavaScript string, pick characters and pieces out of it, tidy it with string methods, and build messages with template literals.
You will be able to
- Write strings with quotes and escapes, and read their length and characters by index
- Use slice, includes, startsWith, toUpperCase, trim and padStart, knowing that each returns a new string
- Build text with template literals: ${} placeholders and text over several lines
Predict · Activity 2 of 7
Predict before you read on: what does this print?
const word = "hello"; word.toUpperCase(); console.log(word);Practice · Activity 3 of 7
Fill in the number so that the program prints Java.
console.log("JavaScript".slice(0, ____));console.log("JavaScript".slice(0, ));Practice · Activity 4 of 7
Match each expression to what console.log prints for it.
Practice · Activity 5 of 7
What does this print?
console.log("Banana".includes("ban"));Brain teaser · Activity 6 of 7
Brain teaser. What does this print?
console.log("Total: ${2 + 3}");Apply · Activity 7 of 7
Mini-task. A till gives you the item " coffee " (with stray spaces), a quantity of 2, a price of 3.2 and the order number 42. Using template literals, print COFFEE x2, then Total: 6.40 EUR, then Order no. 00042.
Check your work against this list
Build it yourself
Read the worked example, then write the exercises. Your code runs in your browser or on your computer and is never uploaded.
Worked example
Printing a train ticket
A booking form sends a passenger name with stray spaces and in lower case. This program tidies it, picks characters and pieces out of it, checks the station name, and prints a three-line ticket with one template literal. Run it, then change the seat to 12 and the name to your own.
main.js
// Formatting a train ticket from raw text.
const rawName = " ada lovelace ";
const from = "Berlin Hbf";
const seat = 7;
const name = rawName.trim();
console.log("name:", name, "length:", name.length);
console.log("initial:", name[0].toUpperCase());
console.log("first name:", name.slice(0, 3));
console.log("from Berlin?", from.startsWith("Berlin"), "main station?", from.includes("Hbf"));
const ticket = `Passenger: ${name.toUpperCase()}
From: ${from}
Seat: ${String(seat).padStart(3, "0")}`;
console.log(ticket);
console.log('She said "bon voyage"\nand waved.');
console.log("rawName is unchanged:", rawName.length);
Run it with
node main.jsOutput
name: ada lovelace length: 12
initial: A
first name: ada
from Berlin? true main station? true
Passenger: ADA LOVELACE
From: Berlin Hbf
Seat: 007
She said "bon voyage"
and waved.
rawName is unchanged: 15- trim() returns a new string without the spaces at the ends: 12 characters instead of 15.
- name[0] is the first character; toUpperCase() makes a capital A from it.
- slice(0, 3) takes indexes 0, 1 and 2: ada.
- The template literal spans three lines, so one console.log prints the whole ticket.
- Single quotes let the text contain double quotes, and \n starts a new line.
- rawName still has its 15 characters: no method changed it.
Change it and run it
Tab indents and Shift+Tab outdents. To leave the editor with the keyboard, press Esc, then Tab.
The first run downloads the JavaScript runner (up to 0.1 MB) and keeps it cached. Your code runs in your browser’s own engine and stays on your device.
Exercises
Exercise 1 of 2
Tidy a name
A form sends the name " Grace Hopper " with stray spaces. Print three lines: Hello, Grace Hopper! (without the extra spaces), Letters: 12 (the length of the tidied name, space included) and Code: GRA (its first three characters in upper case). Work every value out from raw.
Tab indents and Shift+Tab outdents. To leave the editor with the keyboard, press Esc, then Tab.
The first run downloads the JavaScript runner (up to 0.1 MB) and keeps it cached. Your code runs in your browser’s own engine and stays on your device.
Hints
Hint 1
raw.trim() returns the name without the spaces at both ends. Store it: const name = raw.trim();
Hint 2
name.length counts the characters, the space in the middle too.
Hint 3
name.slice(0, 3) gives "Gra"; call toUpperCase() on that result.
Show a solution
One way to solve it. Yours can look different and still pass the checks.
const raw = " Grace Hopper ";
const name = raw.trim();
console.log(`Hello, ${name}!`);
console.log("Letters:", name.length);
console.log("Code:", name.slice(0, 3).toUpperCase());
Run it on your computer
Install ECMAScript 2026 or newer. Save these files in one folder, open a terminal in that folder, and run the commands below.
main.js
const raw = " Grace Hopper ";
// Print three lines:
// Hello, Grace Hopper!
// Letters: 12
// Code: GRA
console.log("Hello, " + raw + "!");
main.test.js
import {test} from 'node:test';
import assert from 'node:assert/strict';
import {runMain} from './learnrun.js';
const lines = async () => (await runMain()).trimEnd().split('\n');
test('greets the tidied name', async () => {
const got = await lines();
assert.equal(got[0], 'Hello, Grace Hopper!', `the first line is ${JSON.stringify(got[0])}, expected "Hello, Grace Hopper!"`);
});
test('prints the length of the tidied name', async () => {
const got = await lines();
assert.equal(got[1], 'Letters: 12', `the second line is ${JSON.stringify(got[1])}, expected "Letters: 12"`);
});
test('prints the code in upper case', async () => {
const got = await lines();
assert.equal(got[2], 'Code: GRA', `the third line is ${JSON.stringify(got[2])}, expected "Code: GRA"`);
});
package.json
{
"type": "module"
}
package.json tells Node.js that the .js files are modules; keep it in the folder.
Run the program:
node main.jsRun the checks (needs learnrun.js in the same folder):
node --testDownload learnrun.jsExercise 2 of 2
A parcel label
Print a parcel label of three lines with one console.log and one template literal: Order #00042 (the order number padded to five digits with zeros), To: HAMBURG (the city in upper case) and Items: 3. Use the three constants; the starter prints only Order #42.
Tab indents and Shift+Tab outdents. To leave the editor with the keyboard, press Esc, then Tab.
The first run downloads the JavaScript runner (up to 0.1 MB) and keeps it cached. Your code runs in your browser’s own engine and stays on your device.
Hints
Hint 1
padStart is a string method, so turn the number into a string first: String(order).padStart(5, "0").
Hint 2
Inside backticks, press Enter where a new line should start; the line break becomes part of the text.
Hint 3
Each value goes into its own placeholder: ${city.toUpperCase()}.
Show a solution
One way to solve it. Yours can look different and still pass the checks.
const order = 42;
const city = "Hamburg";
const items = 3;
console.log(`Order #${String(order).padStart(5, "0")}
To: ${city.toUpperCase()}
Items: ${items}`);
Run it on your computer
Install ECMAScript 2026 or newer. Save these files in one folder, open a terminal in that folder, and run the commands below.
main.js
const order = 42;
const city = "Hamburg";
const items = 3;
// Print, with one template literal over three lines:
// Order #00042
// To: HAMBURG
// Items: 3
console.log("Order #" + order);
main.test.js
import {test} from 'node:test';
import assert from 'node:assert/strict';
import {runMain} from './learnrun.js';
const lines = async () => (await runMain()).trimEnd().split('\n');
test('pads the order number', async () => {
const got = await lines();
assert.equal(got[0], 'Order #00042', `the first line is ${JSON.stringify(got[0])}, expected "Order #00042"`);
});
test('prints the city in upper case', async () => {
const got = await lines();
assert.equal(got[1], 'To: HAMBURG', `the second line is ${JSON.stringify(got[1])}, expected "To: HAMBURG"`);
});
test('prints the number of items', async () => {
const got = await lines();
assert.equal(got[2], 'Items: 3', `the third line is ${JSON.stringify(got[2])}, expected "Items: 3"`);
});
package.json
{
"type": "module"
}
package.json tells Node.js that the .js files are modules; keep it in the folder.
Run the program:
node main.jsRun the checks (needs learnrun.js in the same folder):
node --testDownload learnrun.jsCommon mistakes
Changing one character of a string
const word = "cat";
word[0] = "b";
console.log(word);
What Node.js prints
TypeError: Cannot assign to read only property '0' of string 'cat'Why, and the fix
Strings are immutable, so their characters cannot be assigned. In a module, which is what main.js is here, this stops the program; in older scripts the line is silently ignored, which is worse. Build a new string instead: const fixed = "b" + word.slice(1); gives "bat".
The same quote inside the string
console.log('It's fine');
What Node.js prints
SyntaxError: missing ) after argument listWhy, and the fix
The apostrophe in It's ends the single-quoted string after It, so JavaScript reads s fine' as code and cannot make sense of it. Nothing in the file runs. Use double quotes, "It's fine", escape the apostrophe with a backslash, 'It\'s fine', or use backticks.
A method name with the wrong case
const name = "ada";
console.log(name.toUppercase());
What Node.js prints
TypeError: name.toUppercase is not a functionWhy, and the fix
Method names are case-sensitive, and the method is toUpperCase, with a capital C. name.toUppercase does not exist, so it is undefined, and calling undefined is a TypeError. The same trap waits in toLowerCase and padStart: every word after the first starts with a capital.
JavaScript in the browser: your browser’s own engine, in a sandboxed worker. Syntax errors are located with acorn 8.18.0, MIT. Licence and source
Exit ticket
5 questions, no hints. Score 80% or more to complete the lesson.
Finish every activity above to unlock the exit ticket.