30.5.1JavaScript 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.

30.5.2CDA Pre Import JavaScript Hook

 

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.

30.5.3CDA Post Import JavaScript Hook

 

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.

30.5.4CDA Post Export JavaScript Hook

 

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.

30.5.5Exposed APIs for use in JavaScript Execution Environment

 

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.

30.5.6Example Scripts

 

Examples of various JavaScript hooks.

Each example will be defined individually, but all handlers can be put into the same script.

30.5.6.1CDA Pre Import Scripts

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();
}

30.5.6.2CDA Post Import Scripts

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;
}

30.5.6.3CDA Post Export Script

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);
}