DevAcademy
LearnJavaScriptThe Fetch API
IntermediateJavaScript

The Fetch API

Learn how to make HTTP requests with fetch(), handle the Response object correctly (including the gotcha that fetch only rejects on network failure), send data with POST requests, and cancel requests with AbortController.

Reading Time

18 min

Lesson

Lesson 32 of 48

What fetch() Does

fetch() is the built-in way to make HTTP requests from JavaScript. You call it with a URL, and it returns a Promise — the same kind of Promise you already know how to work with from the Promises and async/await lessons. That Promise resolves to a Response object representing the HTTP response: its status code, headers, and body. Getting the body's actual content, like JSON or text, is a separate, additional step, which trips a lot of people up the first time they use fetch().

A Basic fetch() Call

Try it yourself — edit and run

Console Output

Click “Run” to see the console output here.

The Biggest Gotcha: fetch() Only Rejects on Network Failure

fetch()'s returned promise only rejects if the request never completed — a network failure, a DNS problem, a CORS block, and similar. It does NOT reject just because the server responded with an error status like 404 or 500. A 404 Not Found or a 500 Internal Server Error is still a completed HTTP exchange as far as fetch() is concerned, so the promise fulfills normally with a Response object whose .ok is false and whose .status reflects the error. If you don't check this yourself, your .then() or await will happily treat a failed request as a success.

Checking response.ok Yourself

Try it yourself — edit and run

Console Output

Click “Run” to see the console output here.

Parsing the Response Body

The Response object gives you several methods to read its body, and each one returns yet another Promise, because reading the body is itself an asynchronous streaming operation. response.json() parses the body as JSON and resolves with the resulting value. response.text() resolves with the raw body as a plain string, useful for HTML, plain text, or anything that isn't JSON. You can only read a response's body once — if you need to inspect it more than once, clone it first with response.clone().

response.json() vs. response.text()

Try it yourself — edit and run

Console Output

Click “Run” to see the console output here.

Sending a POST Request

By default, fetch() sends a GET request. To send other HTTP methods, or to include a request body, pass a second argument: an options object. The method property sets the HTTP verb, headers sets any request headers (like telling the server you're sending JSON), and body carries the actual payload. Since body must be a string (or a few other specific types), you typically serialize a JavaScript object into JSON yourself with JSON.stringify() before sending it.

POST with a JSON Body

Try it yourself — edit and run

Console Output

Click “Run” to see the console output here.

Using fetch() with async/await and try/catch

Since fetch() returns a Promise, everything from the async/await lesson applies directly: await the call, and wrap it in a try/catch to handle both genuine network failures (caught automatically, since those are real rejections) and HTTP error statuses (which you still need to check and throw yourself, per the gotcha above). This combination — await plus a manual response.ok check plus try/catch — is the standard, production-ready shape for a fetch() call.

The Standard fetch() Pattern

Try it yourself — edit and run

Console Output

Click “Run” to see the console output here.

Cancelling a Request with AbortController

Sometimes you need to cancel an in-flight fetch() — a user navigates away, types a new search query before the last one finished, or a request is simply taking too long. AbortController gives you a way to do this. You create a controller, pass its .signal to fetch()'s options object, and call controller.abort() whenever you want to cancel. The pending fetch() promise then rejects with an AbortError, which you can detect and handle separately from a genuine network failure.

Aborting a fetch() Request

Try it yourself — edit and run

Console Output

Click “Run” to see the console output here.

Response Object Cheat Sheet

Property / MethodPurpose
response.statusThe numeric HTTP status code (200, 404, 500, etc.)
response.oktrue if status is in the 200-299 range, false otherwise
response.json()Returns a Promise that resolves with the body parsed as JSON
response.text()Returns a Promise that resolves with the body as a raw string
response.headersA Headers object for reading response headers

Always Check response.ok Before Parsing

Make it a habit to check response.ok (or response.status) immediately after every fetch() call, before trying to parse the body. Treating a non-ok response as success, and only discovering the problem when .json() fails to parse an HTML error page, is one of the most common fetch() mistakes.

Course Complete

That's the end of the JavaScript fundamentals section of this course — 47 lessons covering everything from the basics of variables and functions through closures, prototypes, the event loop, memory management, and now the Fetch API. Everything you've learned here — Promises, async/await, and now fetch() — is the foundation you'll use constantly when building real applications that talk to real APIs. Congratulations on making it through the whole curriculum.

Interview Questions

Quick Quiz

1. What does fetch() return?

2. Does fetch()'s promise reject when the server responds with a 500 status?

3. How do you send a JSON payload in a POST request with fetch()?

4. What does response.json() return?

5. How do you cancel a pending fetch() request?