Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 27

Dynamic Content Rendering with Template Literals and Conditionals

Recommended resources

Hello! Welcome to the next step in our JavaScript journey.

In the last lesson, we made our pages interactive using event listeners. You learned to capture user actions like clicks and form submissions and respond to them. You might have noticed in the solution code, we used this syntax: `Welcome, ${username}!`. This is a modern JavaScript feature called a template literal, and it's a far more powerful way to construct strings than the old method of using + signs.

Today, we're going to dive deep into this feature. Our goal is to learn how to use template literals and conditional logic to dynamically render content on a page. This skill is fundamental to building modern web applications, as it allows you to generate complex HTML structures from your data and display them to the user.

1. Goodbye Concatenation, Hello Template Literals

Before template literals were introduced in ES6, building strings from variables was clumsy. You had to "concatenate" (join) everything with plus signs:

// The old way
const name = "Alex";
const unreadMessages = 5;
const notification = "Hello " + name + ", you have " + unreadMessages + " unread messages.";
// Output: "Hello Alex, you have 5 unread messages."

This code is difficult to read and very easy to mess up—forget a space, and the words run together. Creating strings that span multiple lines was even worse, requiring \n characters.

Template literals solve all of these problems. They are defined using backticks (`) instead of single or double quotes.

To see them in action, let's watch a clear explanation.

JavaScript Template Literals

This video, 'JavaScript Template Literals' by Programming with Mosh, perfectly explains the problems with old string-handling methods and how template literals provide a clean, readable solution.

Watch from the beginning to 04:48. Focus on two key concepts: How backticks (`) allow for easy multi-line strings. The ${expression} syntax for embedding variables and even simple calculations directly into the string.

As the video demonstrated, the syntax is much cleaner:

// The new way with template literals
const name = "Alex";
const unreadMessages = 5;
const notification = `Hello ${name}, you have ${unreadMessages} unread messages.`;

const multiLine = `
  This is line one.
  This is line two.
  No special characters needed.
`;

The ${...} placeholder can contain any valid JavaScript expression: a variable, a mathematical operation, or even a function call. This makes them incredibly flexible.


2. Embedding Logic with the Ternary Operator

You can make your templates even more dynamic by embedding conditional logic directly inside them. While you can't write a full if...else block inside ${}, you can use a concise, one-line version called the ternary operator.

The syntax for the ternary operator is:
condition ? expressionIfTrue : expressionIfFalse

It's a compact way to ask a question and choose a value based on the answer. Let's see how it's used.

JavaScript TERNARY OPERATOR in 6 minutes! ❓

The video 'JavaScript TERNARY OPERATOR in 6 minutes!' by Bro Code is a fast and effective guide to this operator.

Watch the entire video (it's short!). Pay special attention to the final example starting at 04:32, where he combines a ternary operator and a template literal to calculate a total—this is a perfect demonstration of today's learning outcome.

Here is a classic, practical example of using a ternary operator inside a template literal to handle pluralization:

const itemsInCart = 1;
const message = `You have ${itemsInCart} item${itemsInCart !== 1 ? 's' : ''} in your cart.`;
console.log(message); // Output: You have 1 item in your cart.

const itemsInCart2 = 5;
const message2 = `You have ${itemsInCart2} item${itemsInCart2 !== 1 ? 's' : ''} in your cart.`;
console.log(message2); // Output: You have 5 items in your cart.

In the expression, we check itemsInCart !== 1. If this is true (the number of items is not 1), we add an 's'. If it's false (the number of items is exactly 1), we add an empty string ''. This is a powerful and common pattern.


3. Dynamically Generating HTML

Now, let's combine these concepts to do something really useful: generate HTML content from data. This is a core task in front-end development. Instead of having static HTML in your .html file, you can create it on the fly with JavaScript.

Template Literals in TypeScript ✍️ - DEV Community

This article, 'Template Literals in TypeScript', has some excellent JavaScript examples that are highly relevant. We'll focus on how to use template literals to build HTML structures.

Please read two specific sections from this article: Find the heading '1. HTML Generation' under 'Real-world Use Cases' and review that short example. Find the heading '2. Using Template Literals with Map' under 'Advanced Techniques' and study that code snippet. \nFocus on how these examples take JavaScript data (an object and an array) and transform it into HTML markup.

The second example from the article, which uses array.map(), is an extremely common and important pattern. You take an array of data, map over it, and for each item in the array, you return an HTML string created with a template literal. Finally, you join() the array of strings into one single block of HTML.

Here's how you'd apply that pattern to render a list of products on a page:

// 1. Some data, maybe from an API in the future
const products = [
  { name: 'Laptop', price: 1200, inStock: true },
  { name: 'Mouse', price: 25, inStock: false },
  { name: 'Keyboard', price: 75, inStock: true }
];

// 2. The container in your HTML file
const productListContainer = document.querySelector('#product-list');

// 3. Generate the HTML string using map() and template literals
const productHtml = products.map(product => {
  // Use a ternary operator for the stock status!
  const stockStatus = product.inStock ? 'In Stock' : 'Out of Stock';

  return `
    <div class="product-card">
      <h3>${product.name}</h3>
      <p>Price: $${product.price}</p>
      <p>Status: ${stockStatus}</p>
    </div>
  `;
}).join('');

// 4. Inject the generated HTML into the DOM
productListContainer.innerHTML = productHtml;

Here, we used .map() to transform each product object into an HTML string, and a ternary operator to conditionally display the stock status. Then, we set the .innerHTML property to render our dynamic content on the page.


4. Hands-On Practice

It's time to put it all together.

  1. Create a new folder for this exercise and add index.html and script.js files.
  2. Use the following code for your files. Your task is to complete the script.js file.

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Dynamic Content Practice</title>
    <style>
        body { font-family: sans-serif; display: flex; justify-content: center; align-items: center; height: 100vh; background-color: #f0f2f5; }
        .profile-card { width: 300px; background: white; border-radius: 10px; box-shadow: 0 4px 8px rgba(0,0,0,0.1); padding: 20px; text-align: center; }
        .status { font-weight: bold; }
        .status.online { color: #28a745; }
        .status.offline { color: #6c757d; }
    </style>
</head>
<body>
    <div id="profile-container">
        <!-- Profile card will be rendered here by JavaScript -->
    </div>
    <script src="script.js"></script>
</body>
</html>

script.js
Now, complete the script.js file to render a user profile card.

// The data for our user
const user = {
  name: 'Jane Doe',
  username: '@janedoe',
  isOnline: true,
  followers: 452
};

// Select the container element from the DOM
const profileContainer = document.querySelector('#profile-container');

// --- Your Turn: Write the code here ---

// Task 1: Create a function called renderUserProfile that takes a user object as an argument.

// Task 2: Inside the function, use a template literal to create an HTML string for a profile card.
// The card should be a div with the class "profile-card".
// It should display the user's name in an <h2> tag and their username in a <p> tag.

// Task 3: Add another <p> tag for the status. Use a ternary operator based on the `isOnline` property.
// If the user is online, the paragraph should be: `<p class="status online">Status: Online</p>`
// If the user is offline, it should be: `<p class="status offline">Status: Offline</p>`
// Hint: You can use a ternary operator to determine the class name AND the text content.

// Task 4: Finally, set the `innerHTML` of the `profileContainer` to the HTML string you created.

// Task 5: Call your `renderUserProfile` function with the `user` object to make the card appear.


// --- Solution ---
function renderUserProfile(userData) {
  const cardHtml = `
    <div class="profile-card">
      <h2>${userData.name}</h2>
      <p>${userData.username}</p>
      <p class="status ${userData.isOnline ? 'online' : 'offline'}">
        Status: ${userData.isOnline ? 'Online' : 'Offline'}
      </p>
      <p>Followers: ${userData.followers}</p>
    </div>
  `;
  
  profileContainer.innerHTML = cardHtml;
}

renderUserProfile(user);

// Bonus: Try changing `isOnline` to `false` in the user object and see the card update on page reload!

Conclusion

Great job! You've just learned one of the most powerful and common techniques for building modern user interfaces. By combining data with template literals and conditional logic, you can create dynamic, data-driven components.

Key Takeaways:

  • Template Literals: Use backticks (`) for cleaner, more readable strings, especially for multi-line content.
  • Expression Interpolation: Embed any JavaScript expression directly into a string with ${...}.
  • Ternary Operator: Use condition ? valueIfTrue : valueIfFalse for concise conditional logic inside your templates.
  • Dynamic Rendering: The pattern of mapping over data to generate an HTML string and then setting element.innerHTML is a cornerstone of front-end development.

In our next lesson, we'll put all of your recent learning into practice with our first Mini Project: adding a light/dark theme toggle to the personal profile site. You'll be using DOM manipulation, event listeners, and the conditional logic you learned today to dynamically change the site's appearance.