Using jQuery.ajax() to Invoke ServiceNow REST APIs - ben-vargas/servicenow-wiki GitHub Wiki

jQuery.ajax() provides a straightforward and asynchronous way to interact with ServiceNow’s REST APIs from client-side scripts. By making direct AJAX calls, you can dynamically create, read, update, or delete ServiceNow records without refreshing the page, improving user experience and application performance.

This guide shows examples of creating an Incident record (using a POST request) and retrieving a User record by sys_id (using a GET request). The provided code includes checks to ensure valid input parameters, proper handling of return values, and robust error logging.


Prerequisites

  • jQuery Context:
    The $j variable is commonly available in ServiceNow client-side environments (e.g., classic UI pages and forms).

  • Valid Authentication:
    The code uses X-UserToken in the request headers. ServiceNow automatically handles authentication for logged-in users. Ensure the user has the required roles and permissions for the targeted table actions.

  • Proper Permissions:
    Your instance’s ACLs and roles govern access. Confirm that the user session can create incidents or query user records before attempting these requests.


Example: Creating an Incident (POST Request)

The function below sends a POST request to the ServiceNow Table API, creating a new Incident record. It includes checks and error handling to ensure a smooth user experience.

function onClickREST() {
    // Prepare the incident data
    var incidentData = { short_description: "This is a test short description." };

    $j.ajax({
        method: "POST",
        url: "/api/now/table/incident",
        data: JSON.stringify(incidentData),
        contentType: "application/json",
        headers: { "X-UserToken": window.g_c }
    })
    .done(function(data, status, jqXHR) {
        if (!data || !data.result) {
            console.error('Unexpected response format. No "result" found.');
            return;
        }

        console.log('Incident created successfully.');
        console.log('Status:', status);
        console.log('Created Incident Short Description:', data.result.short_description || 'N/A');
    })
    .fail(function(jqXHR, status, error) {
        console.error('Failed to create incident.');
        console.error('Status:', status);
        console.error('Error:', error || 'No error details provided.');
    });
}

Key Points:

  • Response Validation:
    Ensures data and data.result exist, preventing null reference errors.

  • Error Handling:
    Logs detailed messages on both success and failure, aiding in troubleshooting.


Example: Retrieving a User Record (GET Request)

The following onChange client script fetches a user record via a GET request, filtering by sys_id. It verifies input, checks the response structure, and logs warnings if data is missing or unexpected.

function onChange(control, oldValue, newValue, isLoading, isTemplate) {
    // Avoid making calls if the field is still loading or empty
    if (isLoading || !newValue) {
        return;
    }

    var url = "/api/now/table/sys_user?sysparm_query=sys_id%3D" + encodeURIComponent(newValue);

    $j.ajax({
        method: "GET",
        url: url,
        headers: { "X-UserToken": window.g_c }
    })
    .done(function(data, status, jqXHR) {
        if (!data || !Array.isArray(data.result)) {
            console.warn('No valid result array returned from the server.');
            return;
        }

        if (data.result.length === 0) {
            console.warn('No user found for the provided sys_id:', newValue);
            return;
        }

        var userRecord = data.result[0];
        if (!userRecord || typeof userRecord.last_name === 'undefined') {
            console.warn('User record found, but "last_name" attribute is missing.');
            return;
        }

        console.log('User retrieved successfully.');
        console.log('Status:', status);
        console.log('User Last Name:', userRecord.last_name);
    })
    .fail(function(jqXHR, status, error) {
        console.error('Failed to retrieve user record.');
        console.error('Status:', status);
        console.error('Error:', error || 'No error details provided.');
    });
}

Key Points:

  • Input Safety:
    Checks newValue before constructing the URL and making the AJAX call.

  • Response Validation:
    Validates data.result is an array and that userRecord.last_name exists before use.

  • Warning Messages:
    Logs warnings when the data is missing or unexpected, facilitating quick diagnosis of common issues.


Best Practices

  1. Validate Inputs:
    Confirm that required parameters are provided before making AJAX calls.

  2. Check Response Structure:
    Always verify that the response contains the expected properties (e.g., data.result) before accessing them.

  3. Graceful Error Handling:
    Use .fail() callbacks to log errors. In .done() callbacks, handle unexpected data structures or empty results by logging warnings.

  4. Avoid Hardcoding When Possible:
    Consider storing URLs, table names, or query parameters in configuration variables for easier maintenance.

  5. Secure Your Requests:
    Trusting X-UserToken ensures the user’s session credentials are used. For more complex scenarios, confirm that necessary ACLs and roles are set up properly.


Additional Resources

  • ServiceNow Table API Documentation:
    ServiceNow Developer Site for details on Table API capabilities, query parameters, and response formats.

  • jQuery.ajax() Documentation:
    jQuery Official Docs for advanced configuration options, timeout settings, and retry logic.


Conclusion

By using jQuery.ajax() to call ServiceNow’s REST APIs with appropriate checks and validations, you create more resilient and maintainable scripts. Thorough response handling, careful property checks, and robust error reporting ensure that your integrations work reliably and provide meaningful feedback during both successful operations and unexpected failures.