PDA

View Full Version : "Cannot read property from undefined" when trying to process multiple OBR/OBX


stacy.atx
06-27-2012, 12:21 PM
Hello!

I'm very new to Mirth, but I have tried to search the forums diligently and can't find an answer to my problem. I'm trying to process HL7 files that have multiple OBR and OBX segments and write them to a SQL database with a separate row for each OBX. We're able to successfully write the information to the database, but I'm receiving a "Cannot read property from undefined" Mirth error.

Based upon a helpful Mirth article (http://www.mirthcorp.com/community/wiki/display/mirth/Mapping+Multiple+Segments+to+a+Database), I chose to use a destination filter to parse out the multiple segments. A colleague of mine who knows some JavaScript tweaked the provided script to accomodate our needs. The data now successfully writes to the database as we expect. However, errors are being thrown in Mirth for "Cannot read property "OBX.1" from undefined".

My colleague explained that the error is being thrown because the loop essentially doesn't know to stop when there are no additional OBXs actually present under an OBR, which makes sense. However, we don't know how to proceed from here to fix the code or our setup so that we have the information written to SQL and also do not receive Mirth errors.

I've attached the channel (a work in progress), the error message, and the script, and also posted the script below.

Any advice?

Thank you!
Stacy



// based upon http://www.mirthcorp.com/community/wiki/display/mirth/Mapping+Multiple+Segments+to+a+Database
//first thing you may want to do here is ensure that you are
// only dealing with messages that have the segments you are
// looking for.

if(msg['MSH']['MSH.9']['MSH.9.1'].toString() == "ORU" && msg['MSH']['MSH.9']['MSH.9.2'].toString() == "R01")
{
//the driver will depend on your database. we will use SQL
var driver = "net.sourceforge.jtds.jdbc.Driver";
var address = "jdbc:jtds:sqlserver://ip/db";
var username = "username";
var password = "pw";

var dbConn = DatabaseConnectionFactory.createDatabaseConnection (driver,address,username,password);

//the patient ID to identify my patient

var PID_18_1_PatientID = msg['PID']['PID.18']['PID.18.1'].toString();

var j = 0; //obr segment count
var i = 0; //obx segment count
var k = 0; // previous obr count
//whenever you have more than one segment, Mirth essentially creates an array of them. Which you can access traditionally varname[index].

while(msg['OBR'][j]['OBR.4']['OBR.4.1'].toString() != undefined) {

var OBR_4_1_Identifier = msg['OBR'][j]['OBR.4']['OBR.4.1'].toString();
var OBR_4_2_Value = msg['OBR'][j]['OBR.4']['OBR.4.2'].toString();

// to handle the first OBX segment, since the while loop will fail due to the check using i-1
if(i == 0)
{
var OBX_3_1_Identifier = msg['OBX'][i]['OBX.3']['OBX.3.1'].toString();
var OBX_5_1_Value = msg['OBX'][i]['OBX.5']['OBX.5.1'].toString();

var expression = "INSERT INTO temp_raw_oru_test (PID_18_Account_Number,OBR_4_1_Identifier_Code,OBR _4_2_Identifier_Text,OBX_3_1_Identifier,OBX_5_1_Va lue) values ( '" + PID_18_1_PatientID + "','" + OBR_4_1_Identifier + "', '" + OBR_4_2_Value + "', '" + OBX_3_1_Identifier + "', '" + OBX_5_1_Value + "');";
var result = dbConn.executeUpdate(expression);
i = i + 1;
}
// will insert OBX segments by groups, the obx1.1 resets to 1 whenever it is a new group, so we use the condition below.
// this loop will exit when a new OBX starts & restarts when a new OBR segment is present.
while ( (j != k) || (i > 0 && msg['OBX'][i]['OBX.1']['OBX.1.1'].toString() >= msg['OBX'][i-1]['OBX.1']['OBX.1.1'].toString() ) ) {

var OBX_3_1_Identifier = msg['OBX'][i]['OBX.3']['OBX.3.1'].toString();
var OBX_5_1_Value = msg['OBX'][i]['OBX.5']['OBX.5.1'].toString();

var expression = "INSERT INTO temp_raw_oru_test (PID_18_Account_Number,OBR_4_1_Identifier_Code,OBR _4_2_Identifier_Text,OBX_3_1_Identifier,OBX_5_1_Va lue) values ( '" + PID_18_1_PatientID + "','" + OBR_4_1_Identifier + "', '" + OBR_4_2_Value + "', '" + OBX_3_1_Identifier + "', '" + OBX_5_1_Value + "');";
var result = dbConn.executeUpdate(expression);
i = i + 1;
k = j;
}

j = j + 1;
}
//simply closes the connection to the DB
dbConn.close();
}
//finally you can return whatever you want to do with your filter.
return true;

cory_cole
06-27-2012, 12:56 PM
I am going to cut some code out to enhance the display of the issue...
i = j= k = 0;

while(msg['OBR'][j]['OBR.4']['OBR.4.1'].toString() != undefined) {

if(i == 0)
{
var OBX_3_1_Identifier = msg['OBX'][i]['OBX.3']['OBX.3.1'].toString();
var OBX_5_1_Value = msg['OBX'][i]['OBX.5']['OBX.5.1'].toString();

i = i + 1;
}
on initial time through
is there an ['OBX'][1]?
Can you reference ['OBX'][0] or is it just ['OBX']['OBX.1']...?

while ( (j != k) || (i > 0 && msg['OBX'][i]['OBX.1']['OBX.1.1'].toString() >= msg['OBX'][i-1]['OBX.1']['OBX.1.1'].toString() ) ) {

senthils
06-27-2012, 01:25 PM
thanks for looking into this Cory.

Stacy & I had worked on this and certainly my java skills are way too rusty for this. & we are using mirth for the first time.

we want to write into the DB the data like below, (we actually are inserting specific fields from the messages):
PID, OBR1, OBX1
PID, OBR1, OBX2
PID, OBR1, OBX3
PID, OBR2, OBX1
PID, OBR2, OBX2

In the 2nd condition "(i > 0 && msg['OBX'][i]['OBX.1']['OBX.1.1'].toString() >= msg['OBX'][i-1]['OBX.1']['OBX.1.1'].toString()"
I am trying to quit the inserts when the value of OBX1.1 changes to 1, which implies it is part of a different OBR.

I am not sure how to use just the OBX[i] to achieve that?

upstart33
06-27-2012, 01:25 PM
psudeo_code


var i = 0;
var test

while (msg['OBX']['OBX.1']['OBX.1.1'][i] != null) {
test += msg['OBX'][i]['OBX.1']['OBX.1.1'].toString() + ',';
i++;
}

senthils
06-27-2012, 01:54 PM
the test += msg will concatenate the OBXs into one string, we don't want to do that.

we want each OBX to be inserted in the DB table as a separate row with its corresponding OBR data.

cory_cole
06-27-2012, 02:04 PM
The part that I have added here will check to see if there is a next OBX. I am pretty sure the problem you are having is with the last OBX. You are testing against the OBX that comes after the last (which does not exist).


(i > 0 && msg['OBX'][i+1].toString() && msg['OBX'][i]['OBX.1']['OBX.1.1'].toString() >= msg['OBX'][i-1]['OBX.1']['OBX.1.1'].toString()

senthils
06-27-2012, 02:27 PM
If the condition checks for && msg['OBX'][i+1].toString() , then the last OBX segment will not get loaded into the database, since the i+1 does not exist.

cory_cole
06-27-2012, 02:33 PM
not the first OBX
i > 0 &&

there is a current OBX
msg['OBX'][i].toString() &&

the current OBX is not equal to the previous OBX
msg['OBX'][i]['OBX.1']['OBX.1.1'].toString() >= msg['OBX'][i-1]['OBX.1']['OBX.1.1'].toString()

stacy.atx
06-27-2012, 02:58 PM
Hi Cory,

Thank you for working with us on this! I changed the script to:

while ( (j != k) || (i > 0 && msg['OBX'][i].toString() && msg['OBX'][i]['OBX.1']['OBX.1.1'].toString() >= msg['OBX'][i-1]['OBX.1']['OBX.1.1'].toString() ) ) {

I sent through another HL7 and received a *different* error message referencing that line of the script: "TypeError: Cannot call method "toString" of undefined."

Did I implement the suggestion correctly? Other thoughts?

MPrecup
06-27-2012, 03:14 PM
Instead of using
msg['OBX'][i].toString()
try using
msg['OBX'][i] != undefined

stacy.atx
06-27-2012, 03:49 PM
Ok, so I changed:

msg['OBX'][i].toString()
to
msg['OBX'][i] != undefined

Then I received an error that my OBR segment was undefined, so I further changed:

msg['OBR'][j]['OBR.4']['OBR.4.1'.toString() != undefined)
to
msg['OBR'][j] != undefined)

Now the messages process successfully through Mirth without any error!

However, to give you the full picture, I am also now newly receiving an extra row in my database for the first OBX line that is under the first OBR. That OBX is associated with a null OBR. Senthil is going to help me look at the code tomorrow to see if we have missed a bracket somewhere or something.

OBR1
OBX1 <-- this one is in the database twice, once as associated with OBR1, and once associated with a NULL OBR
OBX2
OBR2
OBX1
OBX2

Thank you everyone!
Stacy

senthils
06-28-2012, 11:34 AM
Thanks guys, we removed the tostring() and it worked
I had to separate the conditions into an if & the while

if (msg['OBX'][i]!= undefined )
{
while ( (j != k) || (i > 0 && msg['OBX'][i]['OBX.1']['OBX.1.1'].toString() >= msg['OBX'][i-1]['OBX.1']['OBX.1.1'].toString() ) ) {

If included the condition within the while condition, we were getting an extra insert record, so we just moved it out of the while condition.

Is this really an efficient way of getting the individual Obr & OBx in to the DB?

senthils
07-17-2013, 04:38 AM
I have attached the updated javascript we ended up using after working with a mirth developer. hope it helps.