On this page:

30.7FHIR Model API

 

The ResourceBuilder object is used to construct FHIR resources.

30.7.1Method: ResourceBuilder.build(resourceType)

 

This method creates a new instance of a FHIR resource of the given type, which can then be populated as necessary.

Inputs:

  • resourceType – The FHIR resource type (e.g. Patient or Observation).

Outputs:

  • Returns a resource instance that can be populated.

Example:

var patient = ResourceBuilder.build('Patient');

// Identifier (note that fields are created on access)
patient.identifier[0].system = 'http://acme.org/mrn';
patient.identifier[0].value = '1002837';

// Name (note that fields are created on access)
patient.name[0].family = 'Smith';
patient.name[0].given[0] = 'John';
patient.name[0].given[1] = 'Edward';

30.7.2Working with Resources

 

The following section describes features that are available when working with resources from within the scripting environment. Many of these examples show a resource being created using the ResourceBuilder utility. Note that the same functionality is avilable for any resources passed into a function, e.g. within an interceptor.

You can always check the type of a resource using the resourceType property. For example:

if (theResource.resourceType === 'Patient') {
   // do something
}

When populating fields in a resource, fields and elements will be auto-created as required. Generally, working with a resource is as simple as navigating the object hierarchy. Child objects and array offsets are created upon access, meaning that the following will not throw any exception.

var patient = ResourceBuilder.build('Patient');
patient.identifier[2].system = 'http://acme.org/mrn';
patient.identifier[1].system = 'http://example.com/mrn';

This same syntax may also be used to read property values. For example, the following code will copy the patient's family name from the first repetition to the second repetition of Patient.name:

var patient = ResourceBuilder.build('Patient');
var familyName = patient.name[0].family;
patient.name[1].family = familyName;

In the case of repeating elements, the use of an array offset is mandatory.

var givenName = patient.name.given; // FAILS
var givenName = patient.name[0].given[0]; // Succeeds

Elements also support an operator called add(fieldName) which adds a new repetition of the given element at the last index. For example:

// Add an instance of the field called 'name' on the Patient
// resource (this returns a FHIR HumanName datatype)
var name = patient.add('name');

// Populate that HumanName
name.family = 'Smith';
name.add('given') = 'John'; // add and populate
name.add('given') = 'Edward';

If you want to log a JSON representation of a resource, you can do so with .toJson(). This can be useful during development but should never be used in a production environment with real data.

Log.info("Patient:\n" + patient.toJson());

This would log something like the following to the system logs:

19:46:28.509 [TEST_MODULE_ID-0-1] INFO  JS.TEST_NODE_ID.TEST_MODULE_ID Log.java:46 - Patient:
{
  "resourceType": "Patient",
  "name": [ {
    "family": "Please don't log",
    "given": [ "PHI/PII" ]
  } ]
}

Adding Extensions

A convenience method called addExtension(url) exists on any FHIR element that is able to accept an extension.

var patient = ResourceBuilder.build('Patient');

// Add an extension with the given url
var extension = patient.addExtension('http://example.com/eye-colour');

// Populate the value[x] field of the extension with a code datatype
extension.valueCode = 'blue';

Note that the value field on the extension is called value[x]. Per FHIR rules, in an instance, this becomes value followed by the name of the datatype. The following shows a few examples of how to populate different datatypes into an extension (although it would be an error to populate more than one datatype).

extension.valueString = 'Hello';

extension.valueDateTime = '2011-01-10T12:12:00Z';

extension.codeableConcept.coding[0].system = 'http://unitsofmeasure.org/';
extension.codeableConcept.coding[0].code = 'mL';
extension.codeableConcept.coding[0].display = 'Millilitres';

Getting Extensions by URL

Similarly, a convenience method called getExtension(url) exists on any FHIR element that is able to accept an extension.

// Get an extension with the given url
var extension = patient.getExtension('http://example.com/eye-colour');

// Parse the value[x] field of the extension with a code datatype
var value = extension.valueCode;

Note again that the value field on the extension is called value[x]. Per FHIR rules, in an instance, this becomes value followed by the name of the datatype.

Adding and Getting Extensions by URL for Primitive Types

When adding and getting extensions with primitive types, the element name should be prefixed with an underscore (i.e. _).

var patient = ResourceBuilder.build('Patient');

// Populate a primitive type
patient.name[0].family = 'Simpson';

// Add an extension on a primitive type with the given url
var addExtension = patient.name[0]._family.addExtension('http://example.com/also-known-as');

// Populate the value[x] field of the extension with a string datatype
addExtension.valueString = 'Bouvier';

// Get an extension on a primitive type with the given url
var getExtension = patient.name[0]._family.addExtension('http://example.com/also-known-as');

// Parse the value[x] field of the extension with a string datatype
var value = getExtension.valueString;

Note again that the value field on the extension is called value[x]. Per FHIR rules, in an instance, this becomes value followed by the name of the datatype.

Looping over Elements

Many elements in FHIR are designed to be repeatable (in FHIR terms, they have a cardinality greater than 0..1). There are two styles that can be used to conveniently loop over these elements. First, the for..in style:

var familyNames = new Array();
for (var index in theBundle.entry) {
   var nextPatient = theBundle.entry[index].resource;
	familyNames.push(nextPatient.name.family);
}

Second, the forEach style:

var familyNames = new Array();
theBundle.entry.forEach(function(nextEntry) {
   var nextPatient = nextEntry.resource;
	familyNames.push(nextPatient.name.family);
});

Note that for simplicity, these techniques may also be used for non-repeating elements.

30.7.3Working with Composition resources

 

If you use build('Composition'), the resultant Composition resource will have additional functionality beyond that of a resource of any other type created with this method. For information about that added functionality, see Composition Resource API.

30.7.4Working with Bundle resources

 

When working with a Bundle resources, the following special methods exist:

Method: entryResources() and entryResources(resourceType)

This method can be used to retrieve an array of the resources in the Bundle within the field Bundle.entry.resource. Optionally you can pass a String parameter indicating the resource type you want.

For example, the following statements retrieve all resources in the Bundle:

var allResources = bundle.entryResources();
var allPatients = bundle.entryResources('Patient');

30.7.5Contained Resources

 

To create a contained resource, simply create a resource but do not assign it an ID, and then assign it directly to the reference element in the parent resource.

The following example shows a contained Specimen resource within an Observation resource.

var observation = ResourceBuilder.build('Observation');

// Create a specimen that will be contained
var specimen = ResourceBuilder.build('Specimen');

// Set some fields on the specimen..
specimen.status = 'available';

// Assign the resource to the reference
observation.specimen = specimen;

30.7.6Meta Elements

 

You can test whether a resource has a particular tag, security label, or profile using the following utility functions:

if (thePatient.meta.hasTag('http://system', 'value')) {
	// do something
}
if (thePatient.meta.hasSecurity('http://system', 'value')) {
	// do something
}
if (thePatient.meta.hasProfile('http://system.com|1.0.0')) {
   // do something
}

30.7.7Removing Data

 

Data can be cleared from a field by calling clear('fieldName'), e.g.:

theObservation.clear('value');
theObservation.clear('comment');
theObservation.referenceRange[0].clear('type');

An object can also have all of its data cleared by calling clear(), e.g.:

theObservation.valueQuantity.clear();