DevNotes

DevNotes

@devnotes ·

JavaScript Part 10: Load data with fetch

Real apps get their data from servers, and JavaScript has to wait for it without freezing the page.

Why waiting is different

Loading data takes time: maybe 100 milliseconds, maybe 5 seconds on a slow connection. If JavaScript stopped and waited, the whole page would freeze, with no scrolling and no clicks. So slow work is asynchronous. JavaScript starts it, carries on with other things, and comes back when the result is ready.

You can see this with a timer:

JavaScript
console.log("one");setTimeout(() => console.log("two"), 1000);console.log("three");// one, three, and a second later, two

Promises

Slow functions like fetch give you a promise: an object that stands for a value that will arrive later. Eventually the promise either succeeds with the value, or fails with an error.

async and await

await pauses your function until a promise settles, without freezing the page. It only works inside a function marked async:

JavaScript
async function loadUser() {  const response = await fetch("https://jsonplaceholder.typicode.com/users/1");  const user = await response.json();  console.log(user.name);  // "Leanne Graham"}
loadUser();

Two awaits, two steps. fetch gets the response's status and headers first. Then response.json() reads the body and turns the JSON text into an object. JSONPlaceholder is a free, fake API made for practice. To try this, open a new tab, type about:blank in the address bar, and paste it into that tab's console. (Most sites, WIK included, don't let their pages call other servers, so their console would refuse.)

When things go wrong

Networks fail, and servers send back errors. Handle both:

JavaScript
async function loadPosts() {  try {    const response = await fetch("https://jsonplaceholder.typicode.com/posts");    if (!response.ok) {      throw new Error(`Server said ${response.status}`);    }    return await response.json();  } catch (error) {    console.error("Couldn't load posts:", error.message);    return [];  }}

try...catch catches any error thrown inside try, whether it came from the network or from your own throw. Watch out: fetch doesn't fail on a 404 or a 500. It only fails when no response arrives at all, like when you're offline. So check response.ok yourself.

Showing it on the page

Putting it together with the DOM from Part 8. The page needs somewhere to put the posts:

HTML
<p id="note"></p><ul id="posts"></ul>
JavaScript
const list = document.querySelector("#posts");const note = document.querySelector("#note");
async function showPosts() {  note.textContent = "Loading...";  const posts = await loadPosts();  note.textContent = posts.length ? "" : "Nothing to show right now.";
  for (const post of posts.slice(0, 5)) {    const item = document.createElement("li");    item.textContent = post.title;    list.append(item);  }}
showPosts();

Notice the loading message and the empty message. Real apps always show something while they wait, and something when it fails. A blank screen makes people think the site is broken.

Sending data

fetch can send data too, like a form does:

JavaScript
async function sendPost() {  const response = await fetch("https://jsonplaceholder.typicode.com/posts", {    method: "POST",    headers: { "Content-Type": "application/json" },    body: JSON.stringify({ title: "Hello", body: "My first post" }),  });  console.log(await response.json());}
sendPost();

JSONPlaceholder answers with your post and an id of 101. It's a practice API, though, so nothing is really saved.

Try it

Fetch https://jsonplaceholder.typicode.com/users and list each user's name and city (user.address.city) on your page, with "Loading..." showing until it arrives.

That's the JavaScript series done. You know enough now to build small apps of your own, and to start React.


Next: React Part 1: What React is, and your first app

javascriptwebdevbeginners

Join WIK to like and reply to DevNotes and see more like this.