Ever stared at your screen wondering why your jQuery Ajax call just… hangs? Maybe it returns nothing. Maybe it fails silently. Maybe it almost works—until it doesn’t. If you’ve been there (most of us have), it’s time to take a deep dive into writing better jQuery Ajax.
Whether you’re enhancing an ASP.NET MVC app, integrating an external API, or just fetching a chunk of data, writing cleaner, more predictable Ajax calls can save hours of debugging—and improve user experience dramatically.
Let’s explore not just how to write Ajax calls, but how to master them using the tools jQuery gives us: .done()
, .fail()
, .always()
, and more.
Why jQuery Ajax Still Matters in 2025
Despite the rise of fetch APIs, Axios, and other modern approaches, jQuery Ajax still powers many production applications—especially legacy enterprise systems using ASP.NET MVC or Web Forms.
Here’s why:
- Stability: It works across browsers and has been rigorously tested over the years.
- Ease of Use: With just a few lines of code, you get powerful async operations with clear syntax.
- Integration: jQuery’s Ajax utilities work seamlessly with Razor Views and C# APIs.
If you’re maintaining or improving an existing app, jQuery Ajax is not just relevant—it’s often essential.
The Usual jQuery Ajax Mistake
Let’s start with what not to do:
$.ajax({
url: '/api/user/details',
method: 'GET',
success: function (data) {
console.log('Success!', data);
},
error: function (err) {
console.error('Oops', err);
}
});
Sure, it works. But it’s callback soup—clunky, error-prone, and hard to maintain. The better way?
Use .done()
, .fail()
, and .always()
for Cleaner, Modular Code
These chainable methods make Ajax calls easier to manage, separate concerns clearly, and provide better error handling.
Example: Better Structure with .done()
and Friends
$.ajax({
url: '/api/user/details',
method: 'GET'
})
.done(function (data) {
console.log('Data received:', data);
})
.fail(function (jqXHR, textStatus, errorThrown) {
console.error('Ajax failed:', textStatus, errorThrown);
})
.always(function () {
console.log('Ajax call completed—success or fail.');
});
Benefits:
- 🧠 Readability: You know exactly what happens on success, failure, or always.
- 🔌 Separation of Concerns: Keeps logic modular and testable.
- 🛡️ More Robust: Handles edge cases gracefully (like network failures).
Real-World Use Case with ASP.NET Core & jQuery Ajax
Say you have an ASP.NET Core controller returning JSON:
C# Controller
[HttpPost("api/user/create")]
public IActionResult Create([FromBody] UserDto user)
{
if (string.IsNullOrWhiteSpace(user.Email))
return BadRequest("Email is required.");
// Simulate saving user
return Ok(new { success = true, userId = 123 });
}
jQuery Ajax Call
$('#saveUserBtn').click(function () {
const user = {
name: $('#name').val(),
email: $('#email').val()
};
$.ajax({
url: '/api/user/create',
method: 'POST',
contentType: 'application/json',
data: JSON.stringify(user)
})
.done(function (response) {
alert('User saved with ID: ' + response.userId);
})
.fail(function (jqXHR) {
alert('Error: ' + jqXHR.responseText);
})
.always(function () {
$('#loadingSpinner').hide();
});
});
Key Takeaways:
Feature | Benefit |
---|---|
.done() | Executes on success — clean, readable |
.fail() | Centralizes error handling |
.always() | Useful for hiding loaders or resetting UI state |
Going Asynchronous with Promises and .then()
While .done()
is jQuery’s native solution, you can also combine Ajax calls with native JavaScript promises using $.Deferred()
or $.when()
.
Example: Chain Multiple Ajax Calls
$.when(
$.ajax('/api/products'),
$.ajax('/api/users')
)
.then(function (productsResponse, usersResponse) {
renderProducts(productsResponse[0]);
renderUsers(usersResponse[0]);
})
.fail(function () {
alert('Something went wrong while fetching data.');
});
✅ Perfect for parallel requests where you need both results before proceeding.
Tips for Writing Better jQuery Ajax
✅ Use contentType
and dataType
Correctly
$.ajax({
url: '/api/items',
method: 'POST',
contentType: 'application/json',
dataType: 'json',
data: JSON.stringify({ id: 1 })
});
contentType
: what you’re sendingdataType
: what you’re expecting to receive
Misconfiguring these is a common cause of bugs—especially with ASP.NET Core APIs.
✅ Avoid Nested Ajax Calls
This is where .then()
or async/await
(via wrappers) helps.
$.ajax('/api/user')
.then(function (user) {
return $.ajax('/api/orders?userId=' + user.id);
})
.then(function (orders) {
console.log('Orders for user:', orders);
});
Cleaner than nesting one call inside another and avoids callback hell.
✅ Show Loaders and Disable Buttons
Improve UX by indicating loading states:
$('#submitBtn').prop('disabled', true);
$('#loader').show();
$.ajax({ ... })
.done(function () { /* handle success */ })
.fail(function () { /* handle error */ })
.always(function () {
$('#submitBtn').prop('disabled', false);
$('#loader').hide();
});
✅ Use try/catch
Logic in Server-Side C# to Return Clear Errors
Example:
[HttpPost("api/data")]
public IActionResult SaveData([FromBody] DataDto dto)
{
try
{
// Process data
return Ok(new { message = "Saved!" });
}
catch (Exception ex)
{
return StatusCode(500, "An error occurred: " + ex.Message);
}
}
Common Pitfalls with jQuery Ajax and How to Avoid Them
Pitfall | Fix |
---|---|
Not using .fail() | Always include it to catch errors |
Incorrect contentType | Use "application/json" for JSON |
Not escaping query strings | Use encodeURIComponent() |
Repeating UI logic | Use .always() for common cleanup |
Not handling status codes | Use jqXHR.status in .fail() |
SEO Tip: Use Ajax without Hurting SEO
If you’re building an SPA-like site and still relying on Ajax to load content, use progressive enhancement:
- Ensure initial content is crawlable
- Use
<noscript>
fallback if necessary - Pre-render where possible (e.g., SSR or hybrid rendering)
External Resources That Help
Conclusion: Write jQuery Ajax Like a Pro
jQuery Ajax is far from outdated—it’s a solid, powerful tool when used correctly. Writing better jQuery Ajax means:
- Using
.done()
,.fail()
, and.always()
for clean async flows - Integrating tightly with your ASP.NET Core APIs
- Avoiding callback hell with
.then()
and$.when()
- Being thoughtful about UX with loaders, error handling, and state resets
Whether you’re maintaining a legacy project or optimizing an existing app, better jQuery Ajax code can dramatically improve user experience and developer sanity.
What’s Next?
Have a tricky jQuery Ajax use case? Share it in the comments!
👉 Want more guides like this? Subscribe to our newsletter and never miss an update.