- Home
- /
- Tutorials
- /
- JavaScript Tutorial
- /
- JavaScript Fetch API
JavaScript Asynchronous
JavaScript Fetch API
fetchrequests data from a server and returns a promise.
The examples below define a small stand-in for fetch so they run without a server.
It behaves like the real thing: it returns a promise for a response object.
Example
Example
javascript
// A stand-in for the network, so this example runs on its own.
function fetch(url) {
return Promise.resolve({
ok: true,
status: 200,
json: function () {
return Promise.resolve({ name: "Ada" });
}
});
}
fetch("/api/user")
.then(function (response) {
return response.json();
})
.then(function (data) {
console.log(data.name);
});The output is Ada.
Against a real server the only difference is where the data comes from.
How fetch Works
fetch returns a promise for a response object.
The response is not the data - response.json() returns another promise for that.
That is why the classic fetch chain has two then steps.
Syntax
Syntax
javascript
fetch(url)
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.log(error));Two promises: one for the response, one for the body.
With async and await
The same request reads more directly with await.
Example
Example
javascript
function fetch(url) {
return Promise.resolve({
ok: true,
json: function () { return Promise.resolve({ name: "Grace" }); }
});
}
async function load() {
const response = await fetch("/api/user");
const data = await response.json();
console.log(data.name);
}
load();Two awaits, matching the two promises.
fetch Does Not Reject on 404
This surprises almost everyone.
A 404 or 500 is still a successful request, so you must check response.ok.
Example
Example
javascript
function fetch(url) {
return Promise.resolve({ ok: false, status: 404 });
}
async function load() {
const response = await fetch("/api/missing");
if (!response.ok) {
console.log("request failed with status " + response.status);
return;
}
console.log("got the data");
}
load();Only a network failure rejects the promise.
Handling Both Kinds of Failure
A complete request checks the status and catches network errors.
Example
Example
javascript
function fetch(url) {
return Promise.reject(new Error("network down"));
}
async function load() {
try {
const response = await fetch("/api/user");
if (!response.ok) throw new Error("status " + response.status);
console.log("loaded");
} catch (error) {
console.log("failed: " + error.message);
}
}
load();The output is failed: network down.
Sending Data
A second argument sets the method, headers and body.
The body must be a string, so objects are passed through JSON.stringify.
Example
Example
javascript
function fetch(url, options) {
return Promise.resolve({
ok: true,
json: function () {
return Promise.resolve({ sent: JSON.parse(options.body).name });
}
});
}
async function save() {
const response = await fetch("/api/user", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ name: "Alan" })
});
const data = await response.json();
console.log(data.sent);
}
save();The output is Alan, read back from what was sent.
Reading Plain Text
response.text() is the right choice when the answer is not JSON.
Example
Example
javascript
function fetch(url) {
return Promise.resolve({
ok: true,
text: function () { return Promise.resolve("hello"); }
});
}
async function load() {
const response = await fetch("/api/greeting");
console.log(await response.text());
}
load();Calling json() on non-JSON would throw a parsing error.
Complete Example
Complete Example
html
<!DOCTYPE html>
<html>
<head>
<title>JavaScript Fetch API</title>
</head>
<body>
<h1>Fetch API</h1>
<p id="out">Loading...</p>
<script>
async function load() {
const out = document.getElementById("out");
try {
const response = await fetch("https://jsonplaceholder.typicode.com/users/1");
if (!response.ok) {
throw new Error("Status " + response.status);
}
const user = await response.json();
out.textContent = user.name + " from " + user.address.city;
} catch (error) {
out.textContent = "Failed: " + error.message;
}
}
load();
</script>
</body>
</html>Try It Yourself
Run the above example in the Try It Editor.
Try a missing address:
Change the id to 999 and watch the status check catch it.
Important Points
fetchreturns a promise for a response.response.json()returns another promise for the data.fetchdoes not reject on 404 or 500.- Check
response.okbefore using the body. - A second argument sets method, headers and body.
Conclusion
fetch is how a page talks to a server.
The two-promise shape and the response.ok trap are the two things to remember.
Everything from the earlier lessons - chaining, await, error handling - applies directly here.
