Skip to main content

Async beforeSend Callback

What Changed

In version 4.x, the beforeSend callback in dicomImageLoader's LoaderOptions has been changed from synchronous to asynchronous, now returning a Promise.

API Change

The beforeSend callback signature has been updated to support async operations:

// Before (3.x)
beforeSend?: (
xhr: XMLHttpRequest,
imageId: string,
defaultHeaders: Record<string, string>,
params: LoaderXhrRequestParams
) => Record<string, string> | void;

// After (4.x)
beforeSend?: (
xhr: XMLHttpRequest,
imageId: string,
defaultHeaders: Record<string, string>,
params: LoaderXhrRequestParams
) => Promise<Record<string, string> | void>;

Migration Guide

Update Synchronous Callbacks

If you have existing synchronous beforeSend callbacks, wrap the return value in a Promise:

import dicomImageLoader from '@cornerstonejs/dicom-image-loader';

// Before (3.x) - Synchronous
dicomImageLoader.init({
beforeSend: function (xhr, imageId, defaultHeaders, params) {
const headers = {
Authorization: 'Bearer ' + getAuthToken(),
'Custom-Header': 'value',
};
return headers;
},
});

// After (4.x) - Async with Promise
dicomImageLoader.init({
beforeSend: function (xhr, imageId, defaultHeaders, params) {
return Promise.resolve({
Authorization: 'Bearer ' + getAuthToken(),
'Custom-Header': 'value',
});
},
});

// Or use async/await syntax
dicomImageLoader.init({
beforeSend: async function (xhr, imageId, defaultHeaders, params) {
return {
Authorization: 'Bearer ' + getAuthToken(),
'Custom-Header': 'value',
};
},
});

Leverage Async Capabilities

Now you can perform asynchronous operations in beforeSend:

// Fetch auth token asynchronously
dicomImageLoader.init({
beforeSend: async function (xhr, imageId, defaultHeaders, params) {
// Can now make async calls
const token = await fetchAuthToken();
const customHeaders = await getCustomHeaders(imageId);

return {
Authorization: 'Bearer ' + token,
...customHeaders,
};
},
});

Benefits

  • Async Operations: Fetch authentication tokens or headers from remote sources
  • Token Refresh: Automatically refresh expired tokens before requests
  • Conditional Headers: Dynamically determine headers based on async checks
  • Better Integration: Works seamlessly with modern async authentication flows

Important Notes

  • The callback must now return a Promise, even for synchronous operations
  • Use Promise.resolve() for immediate values or async/await syntax
  • The XHR request will wait for the Promise to resolve before sending
  • Rejected promises will cause the image load to fail

Why We Changed This

Modern authentication workflows often require asynchronous operations (token refresh, OAuth flows, etc.). Making beforeSend async enables proper integration with these patterns without workarounds.