jQuery & DOM Manipulation

AJAX with jQuery - Part 1

15 min Lesson 26 of 30

Introduction to AJAX with jQuery

AJAX (Asynchronous JavaScript and XML) allows you to update parts of a web page without reloading the entire page. jQuery provides powerful and simple methods to work with AJAX, making server communication seamless and efficient.

What is AJAX?

AJAX enables:

  • Asynchronous Communication: Send and receive data from servers without page refresh
  • Better User Experience: No page flickering or waiting for full reload
  • Faster Interactions: Load only the data you need
  • Dynamic Content: Update specific parts of your page
Note: While AJAX originally stood for "Asynchronous JavaScript and XML", modern applications typically use JSON instead of XML for data exchange.

The $.ajax() Method

The $.ajax() method is jQuery's most powerful AJAX function. It provides complete control over HTTP requests:

Basic Syntax:
$.ajax({
    url: 'https://api.example.com/data',
    method: 'GET',
    success: function(response) {
        console.log('Success:', response);
    },
    error: function(xhr, status, error) {
        console.log('Error:', error);
    }
});

Common $.ajax() Options

Complete Configuration Example:
$.ajax({
    // Request settings
    url: '/api/users',
    method: 'GET',              // HTTP method (GET, POST, PUT, DELETE)
    data: { page: 1, limit: 10 }, // Data to send
    dataType: 'json',           // Expected response type
    timeout: 5000,              // Request timeout (ms)

    // Headers
    headers: {
        'Authorization': 'Bearer token123',
        'X-Custom-Header': 'value'
    },

    // Callbacks
    success: function(data, textStatus, xhr) {
        console.log('Data received:', data);
    },

    error: function(xhr, textStatus, errorThrown) {
        console.log('Request failed:', textStatus);
    },

    complete: function(xhr, textStatus) {
        console.log('Request completed');
    },

    // Events
    beforeSend: function(xhr) {
        console.log('Sending request...');
        $('#loader').show();
    }
});

GET Requests with $.ajax()

Example: Loading User Data
<div id="user-profile">
    <button id="load-user">Load Profile</button>
    <div id="profile-content"></div>
</div>

<script>
$('#load-user').click(function() {
    $.ajax({
        url: 'https://jsonplaceholder.typicode.com/users/1',
        method: 'GET',
        dataType: 'json',
        beforeSend: function() {
            $('#profile-content').html('<p>Loading...</p>');
        },
        success: function(user) {
            var html = '<h3>' + user.name + '</h3>' +
                      '<p>Email: ' + user.email + '</p>' +
                      '<p>Phone: ' + user.phone + '</p>' +
                      '<p>Website: ' + user.website + '</p>';
            $('#profile-content').html(html);
        },
        error: function(xhr, status, error) {
            $('#profile-content').html('<p style="color: red;">Failed to load profile</p>');
        }
    });
});
</script>

POST Requests with $.ajax()

Example: Creating a New Post
<form id="new-post-form">
    <input type="text" id="post-title" placeholder="Title">
    <textarea id="post-body" placeholder="Content"></textarea>
    <button type="submit">Create Post</button>
</form>
<div id="post-result"></div>

<script>
$('#new-post-form').submit(function(e) {
    e.preventDefault();

    var postData = {
        title: $('#post-title').val(),
        body: $('#post-body').val(),
        userId: 1
    };

    $.ajax({
        url: 'https://jsonplaceholder.typicode.com/posts',
        method: 'POST',
        data: JSON.stringify(postData),
        contentType: 'application/json',
        dataType: 'json',
        success: function(response) {
            $('#post-result').html(
                '<div style="color: green;">' +
                'Post created with ID: ' + response.id +
                '</div>'
            );
            $('#new-post-form')[0].reset();
        },
        error: function() {
            $('#post-result').html(
                '<div style="color: red;">Failed to create post</div>'
            );
        }
    });
});
</script>

Handling Response Data

Example: Processing Different Response Types
// JSON Response
$.ajax({
    url: '/api/products.json',
    dataType: 'json',
    success: function(products) {
        products.forEach(function(product) {
            console.log(product.name, product.price);
        });
    }
});

// HTML Response
$.ajax({
    url: '/templates/product-card.html',
    dataType: 'html',
    success: function(html) {
        $('#products-container').append(html);
    }
});

// Text Response
$.ajax({
    url: '/data/readme.txt',
    dataType: 'text',
    success: function(text) {
        $('#content').text(text);
    }
});

// XML Response
$.ajax({
    url: '/data/products.xml',
    dataType: 'xml',
    success: function(xml) {
        $(xml).find('product').each(function() {
            var name = $(this).find('name').text();
            console.log(name);
        });
    }
});

Request Parameters

Example: Sending Query Parameters
// Object notation (recommended)
$.ajax({
    url: '/api/search',
    data: {
        q: 'laptop',
        category: 'electronics',
        minPrice: 500,
        maxPrice: 2000
    },
    success: function(results) {
        console.log(results);
    }
});
// Sends: /api/search?q=laptop&category=electronics&minPrice=500&maxPrice=2000

// String notation
$.ajax({
    url: '/api/search',
    data: 'q=laptop&category=electronics',
    success: function(results) {
        console.log(results);
    }
});
Tip: Always use object notation for data parameters. jQuery will automatically URL-encode the values and handle special characters correctly.

Setting Request Headers

Example: Custom Headers for API Authentication
$.ajax({
    url: '/api/protected-data',
    method: 'GET',
    headers: {
        'Authorization': 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...',
        'X-API-Key': 'your-api-key-here',
        'X-Requested-With': 'XMLHttpRequest'
    },
    success: function(data) {
        console.log('Protected data:', data);
    },
    error: function(xhr) {
        if (xhr.status === 401) {
            console.log('Unauthorized - invalid token');
        }
    }
});

Timeout and Retry

Example: Handling Timeouts
function loadDataWithTimeout() {
    $.ajax({
        url: '/api/slow-endpoint',
        timeout: 3000, // 3 seconds
        success: function(data) {
            $('#result').html('Data loaded successfully');
        },
        error: function(xhr, status, error) {
            if (status === 'timeout') {
                $('#result').html('Request timed out. Please try again.');
            } else {
                $('#result').html('Error: ' + error);
            }
        }
    });
}

// Retry mechanism
function loadDataWithRetry(maxRetries) {
    var attempts = 0;

    function attempt() {
        $.ajax({
            url: '/api/unreliable-endpoint',
            success: function(data) {
                console.log('Success after', attempts + 1, 'attempts');
            },
            error: function() {
                attempts++;
                if (attempts < maxRetries) {
                    console.log('Retry attempt', attempts);
                    setTimeout(attempt, 1000); // Retry after 1 second
                } else {
                    console.log('Failed after', maxRetries, 'attempts');
                }
            }
        });
    }

    attempt();
}

loadDataWithRetry(3);
Warning: Be careful with automatic retry mechanisms. Too many rapid retries can overload servers or trigger rate limiting. Always implement exponential backoff or delays between retries.

The complete() Callback

Example: Cleanup After Request
$('#submit-button').click(function() {
    var $button = $(this);

    $.ajax({
        url: '/api/save-data',
        method: 'POST',
        data: { value: 'test' },
        beforeSend: function() {
            $button.prop('disabled', true).text('Saving...');
            $('#loader').show();
        },
        success: function(response) {
            $('#message').html('<span style="color: green;">Saved!</span>');
        },
        error: function() {
            $('#message').html('<span style="color: red;">Error!</span>');
        },
        complete: function() {
            // Always runs, whether success or error
            $button.prop('disabled', false).text('Save');
            $('#loader').hide();

            // Clear message after 3 seconds
            setTimeout(function() {
                $('#message').empty();
            }, 3000);
        }
    });
});
Practice Exercise:

Create a user search feature:

  1. Add a search input field and button
  2. Use $.ajax() to fetch data from: https://jsonplaceholder.typicode.com/users
  3. Filter users by name based on search input
  4. Display user cards with name, email, and company
  5. Show a loading indicator while fetching
  6. Handle errors gracefully with appropriate messages
  7. Add a "no results" message when search returns empty

Bonus: Add a debounce function to prevent requests on every keystroke.

Best Practices

  • Always handle errors: Provide meaningful error messages to users
  • Use loading indicators: Show visual feedback during requests
  • Set appropriate timeouts: Prevent indefinite waiting
  • Disable UI during requests: Prevent duplicate submissions
  • Validate data before sending: Reduce unnecessary server requests
  • Use HTTPS: Ensure secure data transmission
  • Handle all status codes: 401 (unauthorized), 404 (not found), 500 (server error)

Summary

In this lesson, you learned:

  • What AJAX is and why it's important
  • How to use $.ajax() with complete configuration
  • Making GET and POST requests
  • Handling different response types (JSON, HTML, text, XML)
  • Setting custom headers and request parameters
  • Implementing timeouts and retry mechanisms
  • Using beforeSend, success, error, and complete callbacks

In the next lesson, we'll explore jQuery's shorthand AJAX methods and advanced techniques like caching, promises, and handling multiple requests.