JavaScript Hooks on CDA Import / Export
CDA exchange allows consumers to supply JavaScript hooks that get executed before and after import and after export.
This allows users to alter/add additional information to documents before processing.
Below are some examples of the scripts that can be provided.
To provide a pre import hook, you need to supply JavaScript that includes the function
onPreImportCDA
.
If supplied, the function will be invoked with a parameters
object that contains the input document (as a text string).
If supplied, this function must return the resulting XML document to process, even if no changes are made!
See below for an example of the onPreImportCDA
handler.
To provide a post import hook, you need to supply JavaScript that includes the function
onPostImportCDA
.
If supplied, the function will be invoked with a parameters
object with accessors to retrieve the created bundle, the operation outcome, and the supplied document (as a text string).
See the examples below for how to utilize the onPostImportCDA
handler.
To provide a post export hook, you need to supply JavaScript that includes the function
onPostExportCDA
.
If supplied, the function will be invoked with a parameters
object with accessors to retrieve the bundle and the created CDA document (provided as an XML string).
If supplied, this function must return the resulting XML document to save, even if no changes were made!
See the examples below for how to utilize the onPostExportCDA
handler.
For information on APIs in the JavaScript execution environment, refer to the standard APIs exposed to the JavaScript environment.
Because CDA utilizes XML documents in the JavaScript hooks, it may be useful to read up on the exposed XML API.
Examples of various JavaScript hooks.
Each example will be defined individually, but all handlers can be put into the same script.
Example 1: Modify the input document to append a new element. Return the newly constructed document.
function onPreImportCDA(params) {
const xmlString = params.getDocument();
const document = XML.createDocument(xmlString);
const patientNameNode = document.getXPathElements("/ClinicalDocument/recordTarget/patientRole/patient/name")[0];
if (!patientNameNode) {
console.error('Could not find patient!');
return;
}
// create new element
const namePrefix = document.createNewElement('prefix');
namePrefix.setTextContent('Dr.');
// add it to the appropriate spot in the xml
patientNameNode.appendChild(namePrefix);
// return the newly formed xml
return document.toXMLString();
}
Example 1: Modify HTTP Verbs on bundle entry requests from POST to GET
function onPostImportCDA(params) {
const bundle = params.getBundle();
const outcome = params.getOutcome();
const strDoc = params.getDocument();
if (bundle.entry && bundle.entry.length) {
const len = bundle.entry.length;
for (let i = 0; i < len; i++) {
const entry = bundle.entry[i];
if (entry.request && entry.request.method) {
if (entry.request.method == 'POST') {
entry.request.method = 'GET';
}
}
}
}
}
Example 2: Update the Patient's date of birth.
function onPostImportCDA(params) {
const bundle = params.getBundle();
// get patient from the bundle
const patient = getPatientFromBundle(bundle);
if (!patient) {
console.error('Could not find patient!');
return;
}
// set the patient birth date
patient.birthDate = '1987-01-04';
}
/* Helper function to extract patient from bundle */
function getPatientFromBundle(bundle) {
const resources = bundle.entryResources();
if (resources && resources.length) {
const len = resources.length;
for (let i = 0; i < len; i++) {
const resource = resources[i];
if (resource.resourceType == 'Patient') {
// there should be exactly 1 patient in the bundle
return resource;
}
}
}
// it should always find a patient
return void 0;
}
Example 1: Look at the Patient from the bundle, and add a new address and gender node to the created XML document. Return the newly parsed XML for saving.
/**
* The CDA Post Export JavaScript hook
*/
function onPostExportCDA(params) {
// retrieve the bundle and the document from the parameters
const bundle = params.getBundle();
const cdaDoc = XML.createDocument(params.getDocument());
// fetch the patient off the bundle
const patient = getPatientFromBundle(bundle);
if (patient) {
updatePatientNode('female', '1234 Second Street',
'Freeburg', 'MI', '49490', 'US', cdaDoc);
}
// return the newly altered document for saving
return cdaDoc.toXMLString();
}
/**
* Retrieves the patient resource from the bundle
*/
function getPatientFromBundle(bundle) {
const resources = bundle.entryResources();
if (resources && resources.length) {
const len = resources.length;
for (let i = 0; i < len; i++) {
const resource = resources[i];
if (resource.resourceType == 'Patient') {
// there should be exactly 1 patient in the bundle
return resource;
}
}
}
// it should always find a patient
return void 0;
}
/**
* Update the patient node with new gender and address information
*/
function updatePatientNode(genderVal, streetVal, cityVal, stateVal,
postalCodeVal, countryVal, cdaDoc) {
// find the patient node on this document
const patientNode = cdaDoc.getXPathElements("/ClinicalDocument/recordTarget/patientRole/patient")[0];
// create the element
const genderElement = cdaDoc.createNewElement('gender');
genderElement.setOrAddAttribute('value', genderVal);
// add it to the dom
patientNode.appendChild(genderElement);
// create address element, and child elements
const addressElement = cdaDoc.createNewElement('addr');
addressElement.setOrAddAttribute('use', 'H');
const street = addressElement.createNewElement('streetAddressLine');
street.setTextContent(streetVal);
addressElement.appendChild(street);
const city = addressElement.createNewElement('city');
city.setTextContent(cityVal);
addressElement.appendChild(city);
const state = addressElement.createNewElement('state');
state.setTextContent(stateVal);
addressElement.appendChild(state);
const postalCode = addressElement.createNewElement('postalCode');
postalCode.setTextContent(postalCodeVal);
addressElement.appendChild(postalCode);
const country = addressElement.createNewElement('country');
country.setTextContent(countryVal);
addressElement.appendChild(country);
// add it to the dom
patientNode.appendChild(addressElement);
}