Introduction
AJAX is commonly used in web applications to communicate with the server without requiring a complete page reload. When an application makes multiple AJAX requests, developers often need common functionality for handling loading indicators, errors, API responses, data formatting, and dynamic UI messages.
Instead of repeating the same logic in every AJAX request, these operations can be placed into reusable JavaScript functions.
This article demonstrates a collection of reusable jQuery AJAX helper functions for:
Showing and hiding a loading indicator.
Handling AJAX errors.
Processing common API responses.
Trimming string values.
Removing the last character from a string.
Loading values dynamically into a dropdown.
Sanitizing values before displaying them.
Displaying dismissible Bootstrap alerts.
The examples are intended to provide a reusable starting point for applications that make frequent AJAX calls.
Prerequisites
Before using the examples, the application should have:
jQuery.
Bootstrap if Bootstrap alerts are being used.
DOMPurify if the dropdown example uses DOMPurify for sanitization.
A server-side endpoint that returns the expected JSON response structure.
An HTML element that can be used as the loading indicator.
For example:
<div id="loadingDiv" style="display:none;">
Loading...
</div>
1. Show a Loading Indicator During AJAX Requests
When an AJAX request is running, users should receive some indication that the application is processing their request.
jQuery provides global AJAX events that can be used for this purpose.
$(document).ajaxStart(function () {
$("#loadingDiv").show();
});
$(document).ajaxStop(function () {
$("#loadingDiv").hide();
});
How It Works
The ajaxStart event is triggered when an AJAX request starts.
$(document).ajaxStart(function () {
$("#loadingDiv").show();
});
The loading element is displayed.
When the AJAX activity finishes, ajaxStop hides the element.
$(document).ajaxStop(function () {
$("#loadingDiv").hide();
});
This approach avoids adding the same show() and hide() statements to every individual AJAX request.
Example Flow
User clicks a button
|
v
AJAX request starts
|
v
Loading indicator appears
|
v
Server processes request
|
v
AJAX activity completes
|
v
Loading indicator disappears
2. Handle Common AJAX Errors
Applications should handle common AJAX failures so that users receive meaningful information instead of an unexplained failure.
A global ajaxError handler can be used:
$(document).ajaxError(function (event, jqXHR, ajaxSettings, exception) {
var msg = '';
if (jqXHR.status === 0) {
msg = 'Not connected. Verify your network connection.';
}
else if (jqXHR.status === 404) {
msg = 'Requested page not found. [404]';
}
else if (jqXHR.status === 500) {
msg = 'Internal Server Error [500].';
}
else if (exception === 'parsererror') {
msg = 'Requested JSON parse failed.';
}
else if (exception === 'timeout') {
msg = 'Timeout error.';
}
else if (exception === 'abort') {
msg = 'AJAX request aborted.';
}
else {
msg = 'Uncaught Error.\n' + jqXHR.responseText;
}
alert(msg);
});
Step-by-Step Explanation
The handler receives information about the failed request:
$(document).ajaxError(function (
event,
jqXHR,
ajaxSettings,
exception
) {
jqXHR.status contains the HTTP status code returned by the server.
For example:
if (jqXHR.status === 404) {
msg = 'Requested page not found. [404].';
}
A 404 generally indicates that the requested resource could not be found.
Similarly:
if (jqXHR.status === 500) {
msg = 'Internal Server Error [500].';
}
indicates a server-side error.
Common Errors
Status/Error | Meaning |
|---|
0
| Request could not connect or was blocked |
404
| Requested resource was not found |
500
| Internal server error |
parsererror
| Response could not be parsed |
timeout
| Request exceeded the configured timeout |
abort
| Request was cancelled |
For production applications, displaying raw responseText to users should be avoided when it may contain internal server details.
3. Process a Common API Response
When multiple AJAX calls use the same response structure, a common response-processing function can reduce duplicate code.
The following function expects a response containing properties such as Success, StatusCode, ResponseText, and ResponseData.
function AjaxSuccess(Data) {
var res = false;
if (Data.Success) {
if (Data.StatusCode == 200) {
if (
(Data.ResponseText == null || Data.ResponseText == "") &&
(Data.ResponseData == null ||
Data.ResponseData.length == 0)
) {
alert(
'Error! Please ask the administrator team to check the error log.'
);
}
else {
res = true;
}
}
}
else {
if (Data.StatusCode == 440) {
alert(Data.ResponseText);
window.location.href = "../Home/SessionExpire";
}
else if (Data.StatusCode == 500) {
alert(Data.ResponseText);
}
else if (Data.StatusCode == 400) {
alert(Data.ResponseText);
}
}
return res;
}
Understanding the Function
The function initially assumes that the operation was not successful:
var res = false;
It then checks whether the API response indicates success:
if (Data.Success)
If the status code is 200, the function checks whether the response contains usable data.
If everything is valid, it returns:
true
Otherwise, it returns:
false
Handling Session Expiration
The following condition handles a 440 response:
if (Data.StatusCode == 440) {
alert(Data.ResponseText);
window.location.href = "../Home/SessionExpire";
}
In applications that use this convention, the client is redirected to a session-expiration page.
The exact status code used for session expiration should match the application's server-side implementation.
4. Trim Whitespace From a String
The following helper removes leading and trailing whitespace:
function TrimData(data) {
return data.replace(/^\s+|\s+$/gm, '');
}
For example:
var name = " John Smith ";
console.log(TrimData(name));
The resulting value is:
John Smith
This can be useful when processing user input before sending it to a server.
For modern JavaScript, String.prototype.trim() is generally simpler for this specific requirement:
var name = " John Smith ";
name = name.trim();
5. Remove the Last Character From a String
The following function removes the final character:
function RemoveLastChar(str) {
var n = str.length;
var newString = "";
for (var i = 0; i < n - 1; i++) {
newString += str[i];
}
return newString;
}
For example:
var value = "ABC";
console.log(RemoveLastChar(value));
Output:
AB
A simpler modern JavaScript alternative is:
var value = "ABC";
var result = value.slice(0, -1);
6. Load Data Into a Dropdown Using AJAX
Applications often need to populate dropdown lists from server-side data.
The LoadDDL function demonstrates this approach.
function LoadDDL(id, defaultSelectedValues) {
defaultSelectedValues =
typeof defaultSelectedValues !== 'undefined'
? defaultSelectedValues
: '';
if (
defaultSelectedValues == -1 ||
defaultSelectedValues == '-1'
) {
defaultSelectedValues = '-1';
}
$.ajax({
type: 'POST',
url: '../xxxx/xxxxx',
async: false,
contentType: 'application/json; charset=utf-8',
success: function (Data) {
if (AjaxSuccess(Data)) {
var ddl = $(id);
ddl.empty();
ddl.append(
$('<option/>', {
value: '-1',
text: 'Select Entity'
})
);
$.each(
Data.ResponseData,
function (index, rowData) {
ddl.append(
$('<option/>', {
value: DOMPurify.sanitize(
rowData.dataID
),
text: DOMPurify.sanitize(
rowData.dataValue
)
})
);
}
);
ddl.val(defaultSelectedValues);
}
}
});
}
Step 1: Set the Default Value
If no default value is supplied, the function uses an empty string:
defaultSelectedValues =
typeof defaultSelectedValues !== 'undefined'
? defaultSelectedValues
: '';
Step 2: Send the AJAX Request
The function sends a POST request:
$.ajax({
type: 'POST',
url: '../xxxx/xxxxx',
The endpoint should be replaced with the actual endpoint from the application.
Step 3: Clear Existing Options
After receiving a successful response, existing dropdown options are removed:
ddl.empty();
Step 4: Add the Default Option
A default option is inserted:
ddl.append(
$('<option/>', {
value: '-1',
text: 'Select Entity'
})
);
Step 5: Add Server Response Data
The returned data is iterated using $.each():
$.each(Data.ResponseData, function (index, rowData) {
Each record is then added to the dropdown.
Step 6: Select the Default Value
Finally:
ddl.val(defaultSelectedValues);
sets the selected value.
7. Sanitize Data Before Displaying It
The dropdown example uses DOMPurify:
DOMPurify.sanitize(rowData.dataValue)
This is intended to reduce the risk of unsafe HTML being inserted into the page.
However, sanitization should not be treated as a replacement for server-side validation and proper output encoding.
When using jQuery to create an <option> element with the text property, the value is handled as text rather than directly inserting arbitrary HTML. The safest approach is still to validate and encode data appropriately at the application boundaries.
8. Display Bootstrap Alert Messages
The article also provides helper functions for displaying different types of messages.
function AlertDismissibleSuccess(Id, Message) {
AlertDismissible('Success', Id, Message);
}
function AlertDismissibleWarning(Id, Message) {
AlertDismissible('Warning', Id, Message);
}
function AlertDismissibleDanger(Id, Message) {
AlertDismissible('Danger', Id, Message);
}
function AlertDismissibleInfo(Id, Message) {
AlertDismissible('Info', Id, Message);
}
These functions provide convenient wrappers around a common alert function.
A corrected implementation can be written as:
function AlertDismissible(type, Id, Message) {
var typeLoc = "purple";
type = type || "";
if (
type.toLowerCase() === "info" ||
type.toLowerCase() === "success" ||
type.toLowerCase() === "warning" ||
type.toLowerCase() === "danger"
) {
typeLoc = type.toLowerCase();
}
var str =
'<div class="alert alert-' +
typeLoc +
' alert-dismissible">' +
'<button type="button" ' +
'class="btn-close" ' +
'data-bs-dismiss="alert"></button>' +
$('<div>').text(Message).html() +
'</div>';
$('#' + Id).html(str);
setTimeout(function () {
$('#' + Id + ' .alert').alert('close');
}, 3000);
}
The important correction here is that the function accepts the same three arguments used by the wrapper functions:
type
Id
Message
The original code called AlertDismissible() with three arguments but declared only two parameters, and it also referenced tType without defining it.
9. Complete Example
The helper functions can be used together in an application.
For example:
<div id="loadingDiv" style="display:none;">
Loading...
</div>
<div id="messageContainer"></div>
<select id="departmentDropdown">
<option value="-1">Select Entity</option>
</select>
A page can then call:
AlertDismissibleSuccess(
"messageContainer",
"Department loaded successfully."
);
The application can display a dismissible success message in the specified container.
Similarly, the dropdown can be populated using:
LoadDDL(
"#departmentDropdown",
"-1"
);
Expected Output
When an AJAX request starts, the loading indicator is displayed:
Loading...
After the AJAX activity finishes, the loading indicator disappears.
When a request succeeds, the dropdown can be populated with values returned by the server:
Select Entity
IT
HR
Finance
Sales
If an AJAX request fails, the configured error handler displays the corresponding error message.
For example:
Requested page not found. [404]
or:
Internal Server Error [500].
For the final C# Corner submission, the author should add screenshots from the actual application showing the loading indicator, populated dropdown, success/error message, and at least one AJAX error scenario.
Important Considerations
Avoid Synchronous AJAX Requests
The original dropdown function uses:
async: false
Synchronous AJAX requests can block the browser while the request is running. This can make the user interface unresponsive.
For modern web applications, asynchronous requests should be preferred.
Instead of:
async: false
the request should normally use the default asynchronous behavior.
Validate Data on the Server
Client-side sanitization and validation should not replace server-side validation.
Values received from the browser should always be treated as untrusted input.
Avoid Exposing Internal Errors
Displaying raw server responses such as:
jqXHR.responseText
can expose implementation details.
Production applications should log detailed exceptions on the server and return an appropriate user-facing error message.
Use Modern JavaScript Where Appropriate
Some helper functions in the original implementation can be simplified using modern JavaScript APIs.
For example:
function RemoveLastChar(str) {
return str.slice(0, -1);
}
and:
function TrimData(data) {
return data.trim();
}
The original implementations can still be useful when maintaining older codebases, but simpler native APIs should generally be preferred when the application's browser/runtime support allows them.
Advantages of Reusable AJAX Helpers
Centralizing common AJAX functionality provides several benefits:
Reduces duplicated JavaScript code.
Provides consistent error handling.
Creates a common loading experience.
Makes API response handling easier to maintain.
Simplifies dropdown population.
Provides reusable UI notification functions.
Makes changes easier because common behavior is maintained in one place.
Conclusion
Reusable JavaScript helper functions can make AJAX-based applications easier to maintain by centralizing common operations such as loading indicators, error handling, API response processing, dropdown population, string manipulation, and user notifications.
The examples in this article demonstrate how jQuery AJAX events and reusable functions can be combined to provide consistent behavior across multiple pages and requests.
When using these patterns in a modern application, developers should also consider asynchronous requests, server-side validation, secure error handling, and appropriate output encoding.
For a production-ready implementation, the reusable functions should be tested against the application's actual API response format and UI components. Adding screenshots and a complete working project will also make the example easier for other developers to reproduce and understand.
Join the conversation! Your thoughts help the community grow.