How to Use the JavaScript Fetch API

Jun 18, 2026 07:00 AM - 1 day ago 623

Introduction

The JavaScript Fetch API is the built-in measurement to make HTTP requests successful modern browsers and successful Node.js 18+. It returns Promises, truthful you tin concatenation .then() calls aliases usage async/await instead of older patterns for illustration XMLHttpRequest aliases jQuery’s $.ajax().

In this tutorial, you will nonstop GET and POST requests, grip HTTP errors correctly, cancel slow requests, and comparison Fetch pinch Ajax and Axios.

fetch('https://jsonplaceholder.typicode.com/users') .then((response) => { if (!response.ok) throw new Error(response.status); return response.json(); }) .then((data) => console.log(data)) .catch((error) => console.error(error));

Deploy your frontend applications from GitHub using DigitalOcean App Platform. Let DigitalOcean attraction connected scaling your app.

Key takeaways

  • The JavaScript Fetch API exposes fetch(url, options). It returns a promise that resolves to a Response object, not parsed JSON.
  • Call response.json(), response.text(), aliases response.blob() to publication the body. Each body-reading method returns its ain Promise.
  • fetch() only rejects connected web failure. A 404 aliases 500 consequence still resolves. Check response.ok aliases response.status earlier you parse the body.
  • For POST requests, group method, headers, and body. Use JSON.stringify() erstwhile you nonstop JSON. See How to Work pinch JSON successful JavaScript.
  • async/await keeps petition codification readable. Pair it pinch try/catch and the aforesaid response.ok checks you usage successful committedness chains.
  • AbortController cancels in-flight requests and sets timeouts. Pass signal successful the options object.
  • Fetch is built into browsers and Node.js 18+. For interceptors aliases automatic JSON parsing, galore teams prime Axios. See React Axios tutorial for a library-based approach.

Prerequisites

To complete this tutorial, you will request the following:

  • A section improvement situation for Node.js. Follow How to Install Node.js and Create a Local Development Environment.
  • A basal knowing of coding successful JavaScript from the How to Code successful JavaScript series.
  • Familiarity pinch Promises and async/await. Read the Promises section of Understanding the Event Loop, Callbacks, Promises, and Async/Await successful JavaScript.

What is the JavaScript Fetch API?

The JavaScript Fetch API is simply a browser and Node.js interface for requesting resources complete HTTP. You walk a URL (or a Request object) to fetch(). The function returns a Promise that resolves erstwhile headers arrive, moreover erstwhile the server returns an correction status.

Concept What it means
fetch() Starts an HTTP request. Second arg sets method, headers, body.
Response Metadata positive assemblage readers for illustration .json() and .text().
Request A reusable explanation of a telephone you tin walk to fetch().

For the afloat specification, see MDN: Fetch API.

Step 1: Getting started pinch Fetch API syntax

The simplest telephone passes only a URL:

fetch(url)

fetch() returns a Promise. Chain .then() to grip a successful response:

fetch(url) .then(function() { // grip the response })

Add .catch() for web errors (offline client, DNS failure, CORS artifact in some cases):

fetch(url) .then(function() { // grip the response }) .catch(function() { // grip the error });

.catch() does not tally erstwhile the server returns 404 aliases 500. You handle those position codes wrong .then() by checking response.ok. The error handling section beneath shows the pattern.

Step 2: Use Fetch to get information from an API

This measurement loads 10 users from the JSONPlaceholder API and renders them in an HTML list.

Create authors.html pinch a heading and an quiet list:

authors.html

<h1>Authors</h1> <ul id="authors"></ul>

Add a book tag. Select the database with getElementById and create a DocumentFragment to clasp database items earlier you connect them to the page:

authors.html

<h1>Authors</h1> <ul id="authors"></ul> <script> const ul = document.getElementById('authors'); const database = document.createDocumentFragment(); const url = 'https://jsonplaceholder.typicode.com/users'; </script>

Call fetch() and cheque response.ok earlier you parse JSON:

authors.html

<script> const ul = document.getElementById('authors'); const database = document.createDocumentFragment(); const url = 'https://jsonplaceholder.typicode.com/users'; fetch(url) .then((response) => { if (!response.ok) { throw new Error(`HTTP ${response.status}`); } return response.json(); }) </script>

The first .then() receives a Response. Calling response.json() returns another Promise pinch the parsed data. Add a 2nd .then() to build database items with map(), createElement, and appendChild:

authors.html

<script> const ul = document.getElementById('authors'); const database = document.createDocumentFragment(); const url = 'https://jsonplaceholder.typicode.com/users'; fetch(url) .then((response) => { if (!response.ok) { throw new Error(`HTTP ${response.status}`); } return response.json(); }) .then((authors) => { authors.forEach((author) => { const li = document.createElement('li'); const sanction = document.createElement('h2'); const email = document.createElement('span'); name.textContent = author.name; email.textContent = author.email; li.appendChild(name); li.appendChild(email); list.appendChild(li); }); ul.appendChild(list); }) .catch((error) => { console.error('Fetch failed:', error); }); </script>

This is the complete authors.html file:

authors.html

<h1>Authors</h1> <ul id="authors"></ul> <script> const ul = document.getElementById('authors'); const database = document.createDocumentFragment(); const url = 'https://jsonplaceholder.typicode.com/users'; fetch(url) .then((response) => { if (!response.ok) { throw new Error(`HTTP ${response.status}`); } return response.json(); }) .then((authors) => { authors.forEach((author) => { const li = document.createElement('li'); const sanction = document.createElement('h2'); const email = document.createElement('span'); name.textContent = author.name; email.textContent = author.email; li.appendChild(name); li.appendChild(email); list.appendChild(li); }); ul.appendChild(list); }) .catch((error) => { console.error('Fetch failed:', error); }); </script>

Open the record successful a browser. You should spot 10 writer names and email addresses. You conscionable completed a GET petition pinch the JavaScript Fetch API.

Step 3: Handle POST requests

fetch() defaults to GET. For POST, walk a 2nd statement pinch method, body, and headers.

new-author.js

const url = 'https://jsonplaceholder.typicode.com/users'; let information = { name: 'Sammy' }; let fetchData = { method: 'POST', body: JSON.stringify(data), headers: { 'Content-Type': 'application/json' } }; fetch(url, fetchData) .then((response) => { if (!response.ok) { throw new Error(`HTTP ${response.status}`); } return response.json(); }) .then((result) => { console.log('Created:', result); }) .catch((error) => { console.error(error); });

JSONPlaceholder echoes your POST assemblage and adds an id field. In a production API, publication the position codification and consequence assemblage to corroborate the grounds was saved.

The Headers interface lets you group petition and consequence headers. On the server side, routes representation HTTP methods to handler functions. See How To Define Routes and HTTP Request Methods successful Express for a Node.js example.

POST pinch a Request object

You tin besides build a Request and walk it to fetch():

new-author-request.js

const url = 'https://jsonplaceholder.typicode.com/users'; let information = { name: 'Sammy' }; let petition = new Request(url, { method: 'POST', body: JSON.stringify(data), headers: { 'Content-Type': 'application/json' } }); fetch(request) .then((response) => response.json()) .then((result) => console.log(result));

fetch() besides supports PUT, PATCH, and DELETE erstwhile you group method in the options object.

Step 4: Handle errors pinch the Fetch API

A resolved fetch() Promise does not mean the petition succeeded. The Promise rejects only erstwhile the petition cannot complete (network down, invalid URL, aborted signal).

Check response.ok (true for position 200–299) aliases inspect response.status:

fetch('https://jsonplaceholder.typicode.com/posts/999') .then((response) => { if (!response.ok) { return Promise.reject({ status: response.status, statusText: response.statusText }); } return response.json(); }) .then((data) => console.log(data)) .catch((error) => { console.error('Request failed:', error.status, error.statusText); });

For async/await, propulsion wrong try/catch erstwhile !response.ok:

async function getPost(id) { const consequence = await fetch(`https://jsonplaceholder.typicode.com/posts/${id}`); if (!response.ok) { throw new Error(`${response.status} ${response.statusText}`); } return response.json(); } getPost(1).then(console.log).catch(console.error);

Read Understanding JavaScript Promises for much connected chaining and rejection.

Step 5: Fetch pinch async/await

async/await is syntactic sweetener complete Promises. It keeps petition codification level and easy to read:

async function fetchUsers(endpoint) { const consequence = await fetch(endpoint); if (!response.ok) { throw new Error(`HTTP ${response.status}`); } const information = await response.json(); return data.map((user) => user.name); } fetchUsers('https://jsonplaceholder.typicode.com/users') .then((names) => console.log(names)) .catch((error) => console.error(error));

You tin return information from an async usability and support chaining .then() on the returned Promise. For a deeper walkthrough of async/await, see Understanding the Event Loop, Callbacks, Promises, and Async/Await successful JavaScript.

Step 6: Cancel requests pinch AbortController

Fetch has nary built-in timeout. Use AbortController to cancel a petition aliases stop it aft a deadline:

const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), 5000); fetch('https://jsonplaceholder.typicode.com/users', { signal: controller.signal }) .then((response) => response.json()) .then((data) => { clearTimeout(timeoutId); console.log(data.length, 'users loaded'); }) .catch((error) => { if (error.name === 'AbortError') { console.error('Request timed out'); } else { console.error(error); } });

AbortController is supported successful existent versions of Chrome, Firefox, Safari, and Edge, and successful Node.js 18+.

Fetch API vs Ajax vs Axios

Feature Fetch API XHR / jQuery Ajax Axios
Installation Native; Node 18+ Native; needs jQuery npm package
Syntax Promise-based Callback aliases Promise Promise-based
JSON parsing Manual .json() Manual Automatic
HTTP errors Manual response.ok Varies Rejects connected 4xx/5xx
Cancellation AbortController xhr.abort() Cancel tokens
Interceptors Not supported Not supported Supported
Interceptors Not supported Not supported Supported

For caller projects that already usage jQuery, read Submitting AJAX Forms pinch jQuery for a comparison of $.ajax() and fetch().

Pick Fetch erstwhile you want zero limitations and your squad is good checking response.ok. Pick Axios erstwhile you request interceptors, simpler error defaults, aliases tighter React integration. See How to Use Vue.js and Axios to Display Data from an API.

Using Fetch API successful JavaScript frameworks

Fetch API successful React

React apps often telephone fetch() wrong useEffect() erstwhile a constituent mounts:

import { useState, useEffect } from 'react'; function App() { const [data, setData] = useState(null); const [error, setError] = useState(null); useEffect(() => { fetch('https://jsonplaceholder.typicode.com/users') .then((response) => { if (!response.ok) throw new Error(response.status); return response.json(); }) .then((json) => setData(json)) .catch((err) => setError(err.message)); }, []); if (error) return <p>Error: {error}</p>; return <div>{data ? JSON.stringify(data) : 'Loading...'}</div>; } export default App;

For a React-focused walkthrough, see How to Call Web APIs pinch the useEffect Hook successful React.

Fetch API successful Vue.js

In Vue 3, telephone fetch() wrong onMounted() aliases the Options API mounted() hook:

<script> export default { data() { return { data: null, error: null }; }, async mounted() { effort { const consequence = await fetch('https://jsonplaceholder.typicode.com/users'); if (!response.ok) propulsion caller Error(response.status); this.data = await response.json(); } drawback (error) { this.error = error.message; } } }; </script>

Many Vue projects usage Axios instead. See Vue.js REST API pinch Axios.

Fetch API successful Angular

Angular ships HttpClient for astir accumulation apps. You tin still telephone native fetch() successful a constituent erstwhile you want a dependency-free call:

import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-data', template: '<p>{{ information | json }}</p>' }) export class DataComponent implements OnInit { data: unknown; async ngOnInit() { const consequence = await fetch('https://jsonplaceholder.typicode.com/users'); if (!response.ok) throw new Error(String(response.status)); this.data = await response.json(); } }

FAQs

1. What is JavaScript Fetch API?

The JavaScript Fetch API is simply a built-in interface for making HTTP requests from browser JavaScript and from Node.js 18+. fetch() returns a Promise that resolves to a Response object. You publication the assemblage pinch methods for illustration .json() or .text(). It replaced XMLHttpRequest for astir caller front-end code.

2. How do you fetch information from an API successful JavaScript?

Call fetch() pinch the API URL, cheque response.ok, past parse the body:

fetch('https://jsonplaceholder.typicode.com/users') .then((response) => { if (!response.ok) throw new Error(response.status); return response.json(); }) .then((data) => console.log(data)) .catch((error) => console.error(error));

The aforesaid shape useful successful Node.js 18+ without other packages. To trial endpoints from the bid line, see How to Use Wget to Download Files and Interact pinch REST APIs.

3. Which is better, Ajax aliases Fetch?

For caller browser code, Fetch is the amended default. It is native, Promise-based, and does not require jQuery. Ajax (via XMLHttpRequest aliases $.ajax()) still fits bequest pages that already dangle connected jQuery. Fetch gives you a smaller runtime footprint and matches modern async/await style. Ajax wrappers tin feel familiar if your codebase already centers connected jQuery.

4. What are the disadvantages of Fetch API?

Fetch does not cull connected HTTP correction position codes, truthful you must cheque response.ok yourself. It does not parse JSON automatically, does not see request interceptors, and does not study upload aliases download progress. Timeouts require AbortController. For apps that request those features retired of the box, a library like Axios is often simpler.

5. What is fetch() successful JavaScript?

fetch() is the world usability that starts a web request. The first argument is simply a URL drawstring aliases Request object. The optional 2nd statement is an options entity pinch method, headers, body, and signal. It ever returns a Promise. The Promise resolves pinch consequence headers moreover erstwhile the server returns an correction code.

Conclusion

The JavaScript Fetch API is supported successful each existent awesome browsers and in Node.js 18+. You tin nonstop GET and POST requests, grip HTTP errors with response.ok, cancel slow calls pinch AbortController, and constitute cleaner code with async/await.

For larger projects, comparison Fetch pinch Axios aliases GraphQL based connected really much control you request complete errors, caching, and information shape. See An Introduction to GraphQL when you want clients to petition only the fields they need.

What’s next

Keep building pinch these JavaScript tutorials:

  • How to Call Web APIs pinch the useEffect Hook successful React
  • React Axios tutorial
  • How to Work pinch JSON successful JavaScript
  • Node.js Express basics
  • How to Install Node.js connected Ubuntu 22.04

Host your API and beforehand extremity on DigitalOcean App Platform with automatic deploys from GitHub. For a dedicated Node.js server, commencement pinch a Droplet and follow How to Set Up a Node.js Application for Production connected Ubuntu 22.04.

Creative CommonsThis activity is licensed nether a Creative Commons Attribution-NonCommercial- ShareAlike 4.0 International License.

More