Fetch in browsers

Contents
GET JSON
POST forms
Check response.ok
Abort slow ones

GET JSON

fetch takes a URL and returns a promise of the response. Await it, then await json for the parsed body. The compiler cannot know the body shape, so declare an interface and pin the parsed value to it:

interface User { id: number; name: string; } async function loadUsers(): Promise<User[]> { const res = await fetch("https://api.example.com/users"); const users = (await res.json()) as User[]; return users; }

Two awaits in a row: one for the headers, one for the body. The function returns a promise of users, and the caller awaits that too.

POST forms

POST sends data instead of asking for it. Pass the method and the body in an options object, with headers that name the format. JSON.stringify turns the object into text the server can read:

async function saveUser(name: string): Promise<void> { await fetch("https://api.example.com/users", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ name }), }); }

The Content-Type header tells the server that JSON is coming. Without it, many backends refuse to parse the body at all.

Check response.ok

fetch only rejects on network failure. A missing page still resolves, so check the ok flag before touching the body. Throw a plain error with the status code, and the caller handles every failure in one catch:

async function loadUsers(): Promise<User[]> { const res = await fetch("https://api.example.com/users"); if (!res.ok) { throw new Error("request failed: " + res.status); } return (await res.json()) as User[]; }

ok is true for statuses 200 through 299. Anything else lands in the throw, and res.status tells exactly which one.

Abort slow ones

Slow requests should not hang the page. An AbortController hands its signal to fetch and cancels on demand: the timer below aborts after five seconds, and the awaited fetch rejects at once. The snippet assumes a module script, where top-level await is legal:

const ctrl = new AbortController(); const timer = setTimeout(() => ctrl.abort(), 5000); try { await fetch("https://api.example.com/users", { signal: ctrl.signal }); } finally { clearTimeout(timer); }

The timer fires abort unless the fetch finishes first. finally clears the timer either way, so no stray timeouts survive the request.

Next: Forms

Article author: Arthur Isaev

Related articles
TypeScript
TypeScript course: zero to hero in 100 lessons
What is TypeScript and where it runs
Install TypeScript
Your first program
tsconfig.json
Basic types
any, unknown, never
Arrays and tuples
Type aliases
Interfaces
Unions and literals
Function types
Parameters
Overloads
Generics
Constraints
Return types
Arrow functions
Callbacks
Narrowing
Assertions
Classes
Constructors
Modifiers
implements
Abstract classes
static
Getters and setters
Enums
ES modules
Decorators
Discriminated unions
Intersections
Mapped types
Conditional types
infer
Template literal types
keyof and typeof
Utility types
satisfies
const assertions
tsc CLI
tsconfig deep dive
Strict mode
Source maps
Declaration files
Linting
Formatting
Debugging
Project references
Publishing packages
Run with Node
npm scripts
argv and env
Files with fs
path and os
JSON IO
Dates
Crypto random
Timers
process
Callbacks to promises
Promises
async and await
Promise.all
Promise.race
HTTPS client
Abort and timeouts
Async error handling
Sequential vs parallel
Event loop
Tests with assert
Test layout
Fixtures
Test doubles
CI tests
DOM basics
DOM events
Fetch in browsers
Forms
Web storage
Npm packages
Bundling concept
SPA concepts
Typed API client
Hand-rolled validation
Iterators and generators
Mixins
Branding nominal types
Result types
Options objects
Builder
Event emitters
Streams
Workers
Deserialization
Capstone: todo CLI
Capstone: JSON API
Capstone: utils library
Modern TypeScript tour
Hero roadmap: the whole course on one page
Install TypeScript on Windows 11
Install TypeScript on Ubuntu
Install TypeScript on Rocky Linux
Install TypeScript on macOS
Install TypeScript on FreeBSD
TypeScript in Docker

Search this site

Channel @aofeed Chat @aofeedchat

Contacts and cooperation:
I recommend our hosting beget.ru
Write to info@urn.su, info@aredel.com if you:
1. Want to write an article for our site or translate an article into your native language.
2. Want to place thematically relevant ads on the site.
3. Ads on my site pass maximum censorship. If you see an ad block unsuitable for school-age children, shocking or misleading - please contact us by e-mail
4. Found a mistake, inaccuracy, bug, etc. on the site. ... .......
5. Articles can be shared on social media by clicking a network icon: