JavaScript Fetch API: Loading, Errors and Cancellation

Web Development Learning Series — Part 4 of 10 · Intermediate A page that loads remote data needs more than a successful request. It needs to explain what happens while waiting, when the server fails, and when the response is not the shape you expected. This lesson adds a small API-driven course panel. You should already understand functions and DOM updates. The example uses a same-origin courses.json file so you can practice without an external service or an API key.

JavaScript DOM Tutorial: Build a Searchable Course List

Web Development Learning Series — Part 3 of 10 · Intermediate

JavaScript becomes easier to learn when each interaction has a clear job. This project filters a course list as the reader types. It teaches events, arrays, and DOM updates without a framework.

The finished feature should handle three situations: a matching query, an empty query that shows everything, and a query with no matches. Decide those behaviors before writing the event handler.

Add the search interface

Save this markup inside the body of a standalone page. Load app.js as a module, which also lets you split the project into files later.

<label for="course-search">Search courses</label>
<input id="course-search" type="search" autocomplete="off">
<p id="result-count" role="status"></p>
<ul id="course-results"></ul>
<script type="module" src="app.js"></script>

Write app.js

const courses = [
  { id: 'html', title: 'HTML Foundations' },
  { id: 'css', title: 'Responsive CSS' },
  { id: 'js', title: 'JavaScript Practice' }
];
const input = document.querySelector('#course-search');
const list = document.querySelector('#course-results');
const count = document.querySelector('#result-count');

function render(query) {
  const term = query.trim().toLowerCase();
  const matches = courses.filter(course =>
    course.title.toLowerCase().includes(term)
  );
  const items = matches.map(course => {
    const item = document.createElement('li');
    item.textContent = course.title;
    return item;
  });
  list.replaceChildren(...items);
  count.textContent = matches.length === 0
    ? 'No courses found. Try another search.'
    : matches.length + ' courses found.';
}
input.addEventListener('input', event => render(event.target.value));
render('');

Serve module-based examples through a local development server; directly opening files can encounter browser restrictions. Check the console if the script fails to load, and verify that the file path matches the actual filename.

Separate calculation from display

Filtering calculates which records match. Rendering creates the visible list. As the project grows, extract the filtering function so it can be checked without a browser. For example, give it the courses and a query, and have it return matching records. Keep DOM queries outside that function.

Use textContent when inserting a course title as text. If data later comes from a user or API, treating it as HTML would change both behavior and risk. You do not need HTML parsing to display a title.

Design useful empty states

“No courses found” is different from “the data could not load.” This local example never requests remote data, so there is no network failure state yet. When you add an API, keep those states separate. A learner should know whether changing their search can help.

The input has a visible label rather than depending on a placeholder. The status region reports the changing count. Test the experience with a keyboard and assistive technology; a rapidly changing announcement may need adjustment if a larger search feature becomes noisy.

Debug deliberately

  1. Search for HTML, html, and a query with spaces around it.
  2. Search for a word that does not exist.
  3. Clear the field and confirm that all courses return.
  4. Add a title containing an ampersand or angle brackets and confirm it displays as text.
  5. Confirm that there is only one event listener, even after repeated searches.

Practice task

Add a difficulty level to each course and a second filter. Decide whether the two filters combine with “and” or “or,” then explain that rule beside the interface. A clear filter model is more useful than a collection of unexplained buttons.

Continue your learning

Previous lesson: Responsive CSS Grid: Build Course Cards That Fit Any Screen. Explore our web development series and the HTML multimedia project.

Reference: Official documentation for this lesson. Examples are learning exercises; adapt and test them for your own application.

Comments

Popular posts from this blog

What Is Multimedia? Examples and a Beginner Course Guide

Video in Multimedia: Formats, Compression and Captions

Internet vs World Wide Web: HTML and Multimedia Explained