Home Blog Implementing AJAX Calls with Fetch API
Back to Blog
Frontend

Implementing AJAX Calls with Fetch API

acretph_jessie
Jessie Allen Añosa
Technical Manager
September 8, 2026
Blog Image

The Fetch API makes working with AJAX much simpler by using promises and a clean syntax. If you handle errors correctly and keep security in mind, you can build very reliable connections between your app and your server. Using these techniques will help you create fast, modern web applications that provide a great experience for your users.

Introduction

Web apps need to talk to servers in the background. Years ago, developers used XMLHttpRequest to handle these tasks, but it was often clunky and hard to read. The Fetch API is the modern standard for making network requests in the browser. It uses promises, which makes your code much cleaner. This guide shows you how to use Fetch for basic requests, handle errors properly, and follow best practices for real-world apps.

Understanding the Fetch API Basics

What Fetch Replaces

  • The old, complex event model of XMLHttpRequest
  • Deeply nested callbacks that make code hard to follow
  • The need to parse different data formats manually

Core Syntax

Here is the basic pattern for a standard GET request:

```javascript

fetch('https://api.example.com/data')

.then(response => response.json())

.then(data => {

// Process the JSON payload

})

.catch(error => {

// Handle network or parsing errors

});

```

A few important things to remember:

  • When you call `fetch`, it returns a promise that resolves to a `Response` object.
  • You can use methods like `.json()`, `.text()`, or `.blob()` to get the data you need.
  • The `catch` block only triggers for actual network failures. HTTP error codes, like 404, will not reject the promise automatically.

Handling HTTP Errors Explicitly

Since the promise doesn't fail just because the server returns an error code, you need to check the `ok` property yourself.

```javascript

fetch('https://api.example.com/resource')

.then(response => {

if (!response.ok) {

throw new Error(`Server responded with ${response.status}`);

}

return response.json();

})

.then(data => {

// Use the data

})

.catch(err => {

console.error('Request failed:', err);

});

```

Common Status Checks

  • 400–499 – Client errors (bad request, unauthorized, not found)
  • 500–599 – Server errors (internal error, service unavailable)

If you throw an error when these statuses appear, your `catch` block can handle every type of failure in one place.

Configuring Request Options

You can pass an options object as the second argument to `fetch` to customize your request.

#### Example: POST Request with JSON Body

```javascript

const payload = { name: 'Alice', role: 'Developer' };

fetch('https://api.example.com/users', {

method: 'POST',

headers: {

'Content-Type': 'application/json',

'Accept': 'application/json'

},

body: JSON.stringify(payload),

credentials: 'include' // Send cookies for same origin requests

})

.then(response => {

if (!response.ok) {

throw new Error(`Failed with status ${response.status}`);

}

return response.json();

})

.then(result => {

console.log('User created:', result);

})

.catch(err => {

console.error('Error creating user:', err);

});

```

#### Important Options

  • `method` – HTTP verb (GET, POST, PUT, DELETE, etc.)
  • `headers` – Key‑value pairs for request headers
  • `body` – Payload for methods that support a body (POST, PUT, PATCH)
  • `mode`: This sets the CORS mode, such as `cors` or `same-origin`.
  • `cache`: Use this to control how the browser handles caching.
  • `credentials`: This determines how cookies are handled during the request.

Working with Query Parameters

Always encode your query strings to keep your URLs safe and valid.

```javascript

const params = new URLSearchParams({

search: 'fetch api',

page: 2,

limit: 20

});

fetch(`https://api.example.com/articles?${params.toString()}`)

.then(res => res.json())

.then(data => {

// Render articles

})

.catch(console.error);

```

The `URLSearchParams` interface automatically handles encoding of special characters.

Parallel and Sequential Requests

Parallel Requests with Promise.all

Running multiple requests at the same time is a great way to speed up your app.

```javascript

const urls = [

'https://api.example.com/users',

'https://api.example.com/posts',

'https://api.example.com/comments'

];

Promise.all(urls.map(url => fetch(url).then(r => {

if (!r.ok) throw new Error(`Failed ${url}`);

return r.json();

})))

.then(([users, posts, comments]) => {

// Process combined data

})

.catch(err => {

console.error('One of the requests failed:', err);

});

```

Sequential Requests with async/await

If you need one request to finish before starting the next, `async` and `await` make the code very readable.

```javascript

async function loadUserData(userId) {

try {

const userRes = await fetch(`https://api.example.com/users/${userId}`);

if (!userRes.ok) throw new Error('User not found');

const user = await userRes.json();

const postsRes = await fetch(`https://api.example.com/users/${userId}/posts`);

if (!postsRes.ok) throw new Error('Posts unavailable');

const posts = await postsRes.json();

return { user, posts };

} catch (e) {

console.error(e);

throw e;

}

}

```

Security Considerations

  • Keep sensitive data out of URLs. Use the request body for things like login credentials.
  • Clean your inputs. Make sure all data is safe before adding it to a request.
  • Check your CORS settings. Ensure the server headers allow your origin to talk to the API.
  • Always use HTTPS. This keeps data safe while it travels over the network.
  • Prevent CSRF attacks. Be careful with requests that change state and use cookies.

Performance Optimizations

  • Use caching. Set the right headers on your server and use the cache option in your fetch calls.
  • Shrink your data. Turn on compression like gzip to make responses smaller.
  • Limit your requests. Throttling on the client side prevents your server from getting overwhelmed.
  • Stay on the same origin. The browser can reuse connections if your API calls go to the same place.

Testing Fetch Calls

  • Mock your calls. Use tools like jest-fetch-mock so you don't have to hit a real server during tests.
  • Check your params. Make sure your tests verify that you are sending the right headers and methods.
  • Test for failure. Force your mocks to fail to make sure your error handling actually works.

Conclusion

The Fetch API makes working with AJAX much simpler by using promises and a clean syntax. If you handle errors correctly and keep security in mind, you can build very reliable connections between your app and your server. Using these techniques will help you create fast, modern web applications that provide a great experience for your users.

Tags:
Frontend
acretph_jessie
Jessie Allen Añosa
Technical Manager
"Kumusta!" I call myself Jessie! A Filipino nomad raised in the Philippines. With years of experience leading technical teams, I thrive at the intersection of technology, strategy, and people management. I specialize in guiding projects from concept to delivery, ensuring solutions are not only functional but scalable and user-focused. Trust me, I know things.

Table of Contents

AcretPhilippines Inc.
Bringing Japanese software development excellence to the Philippine market since 2019.

Acret Philippines Inc.

14th Floor Latitude Corporate Center

Cebu Business Park

Lahug, Cebu City

TEL: 032-344-3847

09:00 AM - 06:00 PM (PHT)

Head Office Acret Inc.

〒650-0011

601 Kenso Building, 2-13-3 Shimoyamate-dori

Chuo-ku Kobe-shi, Hyogo, Japan

TEL:+81 78-599-8511

10:00-17:00 JPT

© 2025 Acret Philippines Inc. All rights reserved.