← Back

AJAX IN JAVASCRIPT

AJAX is a way for the browser and server to exchange data without reloading the whole page.

This note explains AJAX in simple language.

You will learn:

  1. what AJAX is
  2. why AJAX is important
  3. how AJAX works step by step
  4. how to update the page without reloading
  5. how fetch() is used with AJAX
  6. the common beginner mistake with asynchronous data
  7. what query string parameters are
  8. how to use query parameters in a URL

1. What is AJAX?

AJAX means:

Asynchronous JavaScript and XML

AJAX is a way for the browser and server to exchange data without reloading the whole page.

Because of this, websites can feel faster and more interactive.

Today, AJAX usually works with JSON, not XML, but the old name stayed.

Diagram 1. Main idea of AJAX

User does something
-> JavaScript sends request
-> Server sends data back
-> Page updates without full reload

With AJAX, the page does not need to fully refresh every time data changes. Only the needed part of the interface is updated.

2. Why AJAX is useful

AJAX is useful because:

Diagram 2. Without AJAX vs with AJAX

Without AJAX
-> user clicks
-> whole page reloads
-> new content appears

With AJAX
-> user clicks
-> request is sent in background
-> only needed content changes

This is why AJAX is the foundation of dynamic websites.

3. How AJAX works step by step

The AJAX process can be divided into four main steps:

  1. the user performs an action
  2. JavaScript sends an HTTP request
  3. the server processes the request and returns JSON
  4. JavaScript receives the response and updates the interface

Diagram 3. Full AJAX flow

Step 1: User clicks button or submits form
-> Step 2: JavaScript sends HTTP request
-> Step 3: Server processes request
-> Step 4: Server returns JSON
-> Step 5: JavaScript updates page

The most important idea is this:

data changes, but page does not fully reload

4. Example interface

Suppose we have a button and an empty list.

HTML

<button type="button" class="btn">Fetch users</button>
<ul class="user-list"></ul>

When the user clicks the button, JavaScript will request users from the server and then show them on the page.

Diagram 4. Interface idea

Button: "Fetch users"
-> click
-> Request users from server
-> Show users inside <ul>

5. Basic AJAX request with fetch()

const fetchUsersBtn = document.querySelector(".btn");

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

This code does these things:

  1. finds the button
  2. waits for a click
  3. sends a request with fetch()
  4. checks whether the response is successful
  5. converts the response into JSON
  6. gets the users data
  7. handles errors with catch()

Diagram 5. Fetch request flow

Click button
-> fetch(...)
-> response arrives
-> check response.ok
-> response.json()
-> users data
-> use data

The users data becomes available only inside the then() callback where the promise is resolved.

6. Where to update the interface

The second then() is the place where you already have the backend data.

That means this is the correct place to:

Diagram 6. Correct place for DOM update

fetch(...)
-> then(response => ...)
-> then(users => ...)
-> NOW data is available
-> update DOM here

7. Creating HTML from received data

A common pattern is:

  1. use map() on the array of objects
  2. return HTML for each object
  3. join the array of strings into one big string
  4. insert it into the DOM

Example

const fetchUsersBtn = document.querySelector(".btn");
const userList = document.querySelector(".user-list");

fetchUsersBtn.addEventListener("click", () => {
  fetch("https://jsonplaceholder.typicode.com/users")
    .then((response) => {
      if (!response.ok) {
        throw new Error(response.status);
      }
      return response.json();
    })
    .then((users) => {
      const markup = users
        .map((user) => {
          return `<li>
            <p><b>Name</b>: ${user.name}</p>
            <p><b>Email</b>: ${user.email}</p>
            <p><b>Company</b>: ${user.company.name}</p>
          </li>`;
        })
        .join("");

      userList.insertAdjacentHTML("beforeend", markup);
    })
    .catch((error) => console.log(error));
});

Diagram 7. Data to markup flow

users array
-> map()
-> HTML string for each user
-> join("")
-> one big HTML string
-> insertAdjacentHTML(...)
-> render on page

This is a very common frontend pattern when data comes from an API.

8. Cleaner structure with functions

The code becomes easier to read when logic is moved into separate functions:

That is a good practice because the code becomes easier to read and easier to reuse.

Diagram 8. Better code structure

Click handler
-> fetchUsers()
-> then(users => renderUsers(users))
-> catch(error)

Easy rule:

one function = one job

9. The common beginner mistake

One of the most common mistakes is trying to use fetched data outside the then() callback in normal synchronous code.

Wrong example

let globalVar;

fetch("https://jsonplaceholder.typicode.com/users")
  .then(response => response.json())
  .then(users => {
    console.log("users inside then callback: ", users);
    globalVar = users;
    console.log("globalVar inside fetch callback: ", globalVar);
  });

console.log("globalVar outside fetch: ", globalVar); // undefined

10. Why this mistake happens

fetch() is asynchronous.

That means:

Diagram 9. Why undefined appears

Start fetch request
-> JavaScript continues immediately
-> outside console.log runs
-> globalVar is still undefined
-> later the server response arrives
-> then(...) runs

This is one of the most important rules in asynchronous JavaScript:

You cannot use async data in synchronous code before it arrives.

11. Correct way to work with fetched data

All logic that uses the received data should stay inside then(), or be passed from there into another function.

Correct example

fetch("https://jsonplaceholder.typicode.com/users")
  .then((response) => response.json())
  .then((users) => {
    console.log("Received users:", users);
    renderUsers(users);
  })
  .catch((error) => console.log("Error:", error));

Diagram 10. Correct async rule

fetch(...)
-> then(users => {
     use users here
     or pass users to another function
   })

Easy rule:

Data from fetch is available inside then()

12. Query string parameters

Sometimes you want to send extra conditions with your request.

These are called query string parameters.

They are used for things like:

Diagram 11. Query parameter idea

Base URL
-> add extra request conditions
-> server returns more specific result

13. Query parameter syntax

Rules:

Example

fetch("https://jsonplaceholder.typicode.com/users?_limit=7&_sort=name")

Diagram 12. Query string structure

https://jsonplaceholder.typicode.com/users?_limit=7&_sort=name
                                           |         |
                                           |         `- second parameter
                                           `- first parameter

The symbol that starts query parameters is:

?

14. What this query does

In this example:

_limit=7

means:

And:

_sort=name

means:

Diagram 13. Query example meaning

/users?_limit=7&_sort=name
-> get users
-> limit to 7
-> sort by name

15. Why query parameters are useful

They help you ask the backend for more specific data.

Instead of getting everything and processing it only on the frontend, you can ask the server for the exact form you need.

Examples:

Diagram 14. Why query parameters matter

Without parameters
-> server may return too much data

With parameters
-> server returns more precise data

This often makes the app more efficient and cleaner.

16. Easy memory rules

AJAX = server communication without page reload
fetch() = send HTTP request
then() = work with response later
catch() = handle errors
render UI = only after data arrives
? = start query parameters
& = separate query parameters
key=value = one query parameter

17. Quick summary

18. Final conclusion

If you understand these ideas:

AJAX
fetch
then
async data
DOM update
query parameters

then you already have a strong foundation for working with dynamic data in JavaScript.

AJAX is one of the most important frontend topics because modern websites constantly load and update data without reloading the whole page.

← Back