AJAX with jQuery - Part 2
jQuery AJAX Shorthand Methods
jQuery provides convenient shorthand methods for common AJAX operations. These methods simplify your code and make it more readable, while still providing powerful functionality.
$.get() Method
The $.get() method is a shorthand for making GET requests:
$.get(url, data, callback, dataType);
// Example
$.get('/api/users', { page: 1 }, function(data) {
console.log('Users:', data);
}, 'json');
<div id="products-container"></div>
<button id="load-products">Load Products</button>
<script>
$('#load-products').click(function() {
// Simple GET request
$.get('https://fakestoreapi.com/products', function(products) {
var html = '';
products.slice(0, 5).forEach(function(product) {
html += '<div class="product-card">' +
'<h4>' + product.title + '</h4>' +
'<p>Price: $' + product.price + '</p>' +
'<p>' + product.description.substring(0, 100) + '...</p>' +
'</div>';
});
$('#products-container').html(html);
});
});
</script>
$.post() Method
The $.post() method is a shorthand for making POST requests:
$.post(url, data, callback, dataType);
// Example
$.post('/api/register', { username: 'john', email: 'john@example.com' }, function(response) {
console.log('Registered:', response);
}, 'json');
<form id="contact-form">
<input type="text" name="name" placeholder="Name" required>
<input type="email" name="email" placeholder="Email" required>
<textarea name="message" placeholder="Message" required></textarea>
<button type="submit">Send Message</button>
</form>
<div id="form-message"></div>
<script>
$('#contact-form').submit(function(e) {
e.preventDefault();
var formData = {
name: $('[name="name"]').val(),
email: $('[name="email"]').val(),
message: $('[name="message"]').val()
};
$.post('/api/contact', formData)
.done(function(response) {
$('#form-message').html(
'<div class="success">Message sent successfully!</div>'
);
$('#contact-form')[0].reset();
})
.fail(function() {
$('#form-message').html(
'<div class="error">Failed to send message. Please try again.</div>'
);
});
});
</script>
$.getJSON() Method
The $.getJSON() method is specifically designed for fetching JSON data:
<div id="weather">
<button id="get-weather">Get Weather</button>
<div id="weather-info"></div>
</div>
<script>
$('#get-weather').click(function() {
var city = 'London';
var apiKey = 'your-api-key';
var url = 'https://api.openweathermap.org/data/2.5/weather';
$.getJSON(url, {
q: city,
appid: apiKey,
units: 'metric'
}, function(data) {
var html = '<h3>' + data.name + '</h3>' +
'<p>Temperature: ' + data.main.temp + '°C</p>' +
'<p>Weather: ' + data.weather[0].description + '</p>' +
'<p>Humidity: ' + data.main.humidity + '%</p>';
$('#weather-info').html(html);
});
});
</script>
$.load() Method
The $.load() method loads HTML from a server and inserts it directly into selected elements:
<div id="header"></div>
<div id="sidebar"></div>
<div id="content"></div>
<script>
// Load complete files
$('#header').load('/templates/header.html');
$('#sidebar').load('/templates/sidebar.html');
// Load specific portion using selector
$('#content').load('/page.html #main-content');
// Load with callback
$('#content').load('/article.html', function(response, status, xhr) {
if (status === 'error') {
$(this).html('<p>Sorry, content could not be loaded.</p>');
} else {
console.log('Content loaded successfully');
}
});
// Load with parameters
$('#results').load('/search.php', { query: 'jquery', limit: 10 });
</script>
Promise Interface with .done(), .fail(), .always()
All jQuery AJAX methods return a jqXHR object that implements the Promise interface:
// Basic promise chain
$.get('/api/user/1')
.done(function(data) {
console.log('Success:', data);
})
.fail(function(xhr, status, error) {
console.log('Error:', error);
})
.always(function() {
console.log('Request completed');
});
// Multiple handlers
var request = $.getJSON('/api/products');
request.done(function(products) {
console.log('Loaded', products.length, 'products');
});
request.done(function(products) {
$('#product-count').text(products.length);
});
request.fail(function() {
$('#error-message').show();
});
request.always(function() {
$('#loader').hide();
});
Chaining Multiple AJAX Requests
// Load user, then load their posts, then load comments
$.get('/api/user/1')
.done(function(user) {
console.log('User:', user.name);
$('#user-name').text(user.name);
return $.get('/api/user/' + user.id + '/posts');
})
.done(function(posts) {
console.log('Posts:', posts.length);
$('#post-count').text(posts.length);
return $.get('/api/posts/' + posts[0].id + '/comments');
})
.done(function(comments) {
console.log('Comments:', comments.length);
$('#comment-count').text(comments.length);
})
.fail(function(error) {
console.log('Error in chain:', error);
});
Parallel AJAX Requests with $.when()
Use $.when() to execute code after multiple AJAX requests complete:
// Execute multiple requests in parallel
var usersRequest = $.get('/api/users');
var productsRequest = $.get('/api/products');
var categoriesRequest = $.get('/api/categories');
$.when(usersRequest, productsRequest, categoriesRequest)
.done(function(usersData, productsData, categoriesData) {
// All three requests completed successfully
var users = usersData[0]; // First element is the data
var products = productsData[0];
var categories = categoriesData[0];
console.log('Users:', users.length);
console.log('Products:', products.length);
console.log('Categories:', categories.length);
// Initialize dashboard with all data
initDashboard(users, products, categories);
})
.fail(function() {
console.log('One or more requests failed');
$('#error-message').text('Failed to load dashboard data');
})
.always(function() {
$('#loader').hide();
});
function initDashboard(users, products, categories) {
$('#total-users').text(users.length);
$('#total-products').text(products.length);
$('#total-categories').text(categories.length);
}
Global AJAX Event Handlers
jQuery provides global AJAX events that fire for all AJAX requests:
<div id="global-loader" style="display: none;">Loading...</div>
<script>
// Show loader when any AJAX request starts
$(document).ajaxStart(function() {
$('#global-loader').fadeIn();
});
// Hide loader when all AJAX requests complete
$(document).ajaxStop(function() {
$('#global-loader').fadeOut();
});
// Track AJAX activity
var activeRequests = 0;
$(document).ajaxSend(function(event, xhr, settings) {
activeRequests++;
console.log('Request started:', settings.url);
console.log('Active requests:', activeRequests);
});
$(document).ajaxComplete(function(event, xhr, settings) {
activeRequests--;
console.log('Request completed:', settings.url);
console.log('Active requests:', activeRequests);
});
// Global error handler
$(document).ajaxError(function(event, xhr, settings, error) {
console.error('AJAX Error:', settings.url, error);
if (xhr.status === 401) {
window.location.href = '/login';
}
});
// Global success handler
$(document).ajaxSuccess(function(event, xhr, settings) {
console.log('AJAX Success:', settings.url);
});
</script>
AJAX Caching
var cache = {};
function getCachedData(url, forceRefresh) {
// Check if cached and not forcing refresh
if (cache[url] && !forceRefresh) {
console.log('Returning cached data for:', url);
return $.Deferred().resolve(cache[url]).promise();
}
// Fetch from server
console.log('Fetching from server:', url);
return $.get(url).done(function(data) {
cache[url] = data;
});
}
// Usage
$('#load-users').click(function() {
getCachedData('/api/users')
.done(function(users) {
displayUsers(users);
});
});
$('#refresh-users').click(function() {
getCachedData('/api/users', true) // Force refresh
.done(function(users) {
displayUsers(users);
});
});
// Cache with expiration
var cacheWithExpiry = {};
function getCachedDataWithExpiry(url, ttl) {
var now = Date.now();
var cached = cacheWithExpiry[url];
// Check if cached and not expired
if (cached && (now - cached.timestamp < ttl)) {
console.log('Returning cached data');
return $.Deferred().resolve(cached.data).promise();
}
// Fetch from server
return $.get(url).done(function(data) {
cacheWithExpiry[url] = {
data: data,
timestamp: now
};
});
}
// Cache for 5 minutes (300000 ms)
getCachedDataWithExpiry('/api/products', 300000)
.done(function(products) {
displayProducts(products);
});
Request Cancellation
var currentRequest = null;
$('#search-input').on('input', function() {
var query = $(this).val();
// Cancel previous request if still running
if (currentRequest) {
currentRequest.abort();
console.log('Previous request cancelled');
}
// Don't search if query is too short
if (query.length < 3) {
$('#search-results').empty();
return;
}
// Start new request
currentRequest = $.get('/api/search', { q: query })
.done(function(results) {
displaySearchResults(results);
})
.fail(function(xhr) {
if (xhr.statusText === 'abort') {
console.log('Request was aborted');
} else {
console.log('Search failed');
}
})
.always(function() {
currentRequest = null;
});
});
function displaySearchResults(results) {
var html = '';
results.forEach(function(result) {
html += '<div class="result-item">' + result.title + '</div>';
});
$('#search-results').html(html);
}
Default AJAX Settings
// Set default options for all AJAX requests
$.ajaxSetup({
timeout: 10000,
cache: false,
headers: {
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
},
beforeSend: function(xhr) {
var token = localStorage.getItem('auth_token');
if (token) {
xhr.setRequestHeader('Authorization', 'Bearer ' + token);
}
},
error: function(xhr) {
if (xhr.status === 401) {
console.log('Unauthorized - redirecting to login');
window.location.href = '/login';
}
}
});
// All subsequent AJAX calls will use these defaults
$.get('/api/protected-resource')
.done(function(data) {
console.log('Data:', data);
});
Working with Different Content Types
// Sending JSON
$.ajax({
url: '/api/data',
method: 'POST',
contentType: 'application/json',
data: JSON.stringify({ name: 'John', age: 30 }),
success: function(response) {
console.log('JSON sent successfully');
}
});
// Sending form-encoded data (default)
$.ajax({
url: '/api/data',
method: 'POST',
data: { name: 'John', age: 30 },
success: function(response) {
console.log('Form data sent successfully');
}
});
// Sending FormData (for file uploads)
var formData = new FormData();
formData.append('name', 'John');
formData.append('file', $('#file-input')[0].files[0]);
$.ajax({
url: '/api/upload',
method: 'POST',
data: formData,
processData: false,
contentType: false,
success: function(response) {
console.log('File uploaded successfully');
}
});
Build a multi-step data loading dashboard:
- Create three parallel requests to load users, posts, and comments using $.when()
- Display a global loading indicator while requests are in progress
- Show statistics: total users, posts, and comments
- Implement caching with 2-minute expiration
- Add a "Refresh" button to force reload from server
- Display the most active user (user with most posts)
- Show recent posts with comment counts
- Handle errors gracefully and show appropriate messages
API Endpoints:
- Users: https://jsonplaceholder.typicode.com/users
- Posts: https://jsonplaceholder.typicode.com/posts
- Comments: https://jsonplaceholder.typicode.com/comments
Summary
In this lesson, you learned:
- jQuery's shorthand AJAX methods: $.get(), $.post(), $.getJSON(), $.load()
- Using the Promise interface with .done(), .fail(), and .always()
- Chaining sequential AJAX requests
- Making parallel requests with $.when()
- Global AJAX event handlers for tracking all requests
- Implementing caching strategies
- Cancelling ongoing requests
- Setting global AJAX defaults with $.ajaxSetup()
- Working with different content types
Next, we'll explore working with forms and serialization to efficiently collect and send form data via AJAX.