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 orasync/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.