ironbridgecorp / hl7-standard

Simple, Lightweight HL7 module for tranforming, manipulating, or creating HL7 messages.
Apache License 2.0
49 stars 13 forks source link

Get multiple fields like you can get multiple segments #10

Open d31741237412d opened 1 year ago

d31741237412d commented 1 year ago

First of all, thank you for this wonderful library; it has helped me immensely in parsing hl7 messages.

One thing that I would like to ask:

When dealing with fields the only way seems to be using the get method which only returns the first field, while with segments there are 2 different methods getSegment and getSegments. In order to handle this I'm currently doing something like the following:

let pidSegment = hl7.getSegment("PID");
const pid3Length = pidSegment["data"]["PID.3"].length;
for (let i = 0; i < pid3Length; i++) {
  // process fields using pidSegment["data"]["PID.3"][i]
}

Is this the proper way to do it? I would assume that directly changing the "data" part of the segment is not a good idea (since all other data changes are encouraged to use the built-in methods like set) but I can't find any other way to do it.

The documentation does not present any example of how to handle an array of fields but it focuses mostly on the segment part of the features.

Thanks in advance for any insight that you might be able to provide.

ironbridgecorp commented 1 year ago

Thank you, we are glad you are finding value in the library!

The get and set methods accept 3 indexes to do this, but I can see where a helper function would be valuable for what you are trying to do, so it's possible we would look to add that functionality.

For the get and set methods the indexes are explained at a high level in the docs:

https://github.com/ironbridgecorp/hl7-standard#get https://github.com/ironbridgecorp/hl7-standard#set

The first index is the index of the segment, ie if the segment is a repeating segment like an NTE. In your example, its a PID segment so this value would be 0 or null. The second index is the repeating section index. The third index is for repeating fields.

Here's an example of setting PID.11 with multiple addresses:

      for (let [idx, address] of address_data.entries()) {
        console.log('index: ', idx);
        msg.set('PID.11.1', address.line_1, 0, idx);
        msg.set('PID.11.2', address.line_2, 0, idx);
        msg.set('PID.11.3', address.city, 0, idx);
        msg.set('PID.11.4', address.state, 0, idx);
        msg.set('PID.11.5', address.postal_code, 0, idx);
        msg.set('PID.11.6', 'US', 0, idx);
      }
      // PID|||||||||||123 Example One^^Pittsburgh^PA^15226^US~456 Sample Rd^^Tomato^PA^15090^US~789 Place Street^^Cranberry^PA^15317^US||||||||||||||||||||

Here's an example of parsing repeating PID.3 identifiers:

//PID|||4019060^^^^EPI~1234^^^^EX~987654^^^^MRN||
let pid = msg.getSegment('PID');
      var patient_identifiers = [];
      var pid_ids = Array.isArray(pid.data['PID.3']) ? pid.data['PID.3'] : [pid.data['PID.3']];

      for (let pid3 of pid_ids) {
        let identifier = {
          value: pid3['PID.3.1'],
          type: pid3['PID.3.5']
        }
        patient_identifiers.push(identifier);
      }

      // [{
      //     value: '4019060',
      //     type: 'EPI'
      //   },
      //   {
      //     value: '1234',
      //     type: 'EX'
      //   },
      //   {
      //     value: '987654',
      //     type: 'MRN'
      //   }
      // ]

And another example using the get method with the indexes to retrieve the MRN value:

//PID|||4019060^^^^EPI~1234^^^^EX~987654^^^^MRN||

      let pid = msg.getSegment('PID');

      var pid_ids = Array.isArray(pid.data['PID.3']) ? pid.data['PID.3'] : [pid.data['PID.3']];

      var mrn;
      for (var i = 0; i < pid_ids.length; i++) {
        if (pid.get('PID.3.5', i) === 'MRN') {
          mrn = pid.get('PID.3.1', i);
        }
      }

      // mrn: 987654

You can also look at the unit tests to see additional examples of it. I think a helper function for looping repeating components within a segment would be a good addition, but I hope in the meantime these examples are helpful and serve as a work around.