web stats
Enum Status and inherited method toString() not working - Mirth Community

Go Back   Mirth Community > Mirth Connect > Support

Reply
 
Thread Tools Display Modes
  #1  
Old 02-25-2020, 03:15 AM
heiira heiira is offline
What's HL7?
 
Join Date: Feb 2020
Location: Germany
Posts: 2
heiira is on a distinguished road
Default Enum Status and inherited method toString() not working

I am working with Mirth v.3.8.1

I build an array of all destination response status to check whether one of them run into an error.

Code:
var destinationStatus = [];

for each (metaDataId in message.getConnectorMessages().keySet().toArray()) {
	if (metaDataId > 0) {
		var status = $r('d'+metaDataId).getStatus().toString();
		destinationStatus.push(status);
	}
}
Sadly the .toString() method which should be inherited from class java.lang.Enum seems not to work properly (source: Status@javadocs.mirthcorp).

If I inspect (typeof(status); ) the variable status before pushing it into the array it says 'object' not 'string'.

Thus working with destinationStatus.indexOf('SENT') e.g. does not work, even though a message has the status SENT it is not recognized.

If I manipulate the status via ''+status it works fine:

Code:
var destinationStatus = [];

for each (metaDataId in message.getConnectorMessages().keySet().toArray()) {
	if (metaDataId > 0) {
		var status = ''+$r('d'+metaDataId).getStatus().toString();
		destinationStatus.push(status);
	}
}
Any idea what I am missing? Thanks in advance!
Reply With Quote
  #2  
Old 02-25-2020, 01:19 PM
agermano agermano is offline
Mirth Guru
 
Join Date: Apr 2017
Location: Indiana, USA
Posts: 1,170
agermano is on a distinguished road
Default

Since Status is a Java class, when you call the toString method it returns an instance of java.lang.String, which typeof will tell you is an object, and not a javascript string primative.

Despite this, you shouldn't have an issue sticking that Java String into the javascript array. Where you may have issues later is using strict comparisons. Switch statements inherently use strict comparisons.

Code:
// this is false, because as you noticed, typeof returns string and
// object, which can't evaluate to true
'hello' === new java.lang.String('hello')

// this is true (I think because the Java String is coerced to a
// javascript string)
'hello' == new java.lang.String('hello')
Any string concatenation in javascript will return a javascript string, even if you are concatenating two java.lang.Strings.

A more explicit way to convert it would be to do
Code:
var status = String($r('d'+metaDataId).getStatus().toString());

// or even this, which will implicitly call toString for you
var status = String($r('d'+metaDataId).getStatus());
Reply With Quote
  #3  
Old 03-05-2020, 11:00 PM
heiira heiira is offline
What's HL7?
 
Join Date: Feb 2020
Location: Germany
Posts: 2
heiira is on a distinguished road
Default

Thanks agermano, that was my problem! The String() variant looks way more professional than ''+.

Adjusted to your second suggestion and works like a charm!
Reply With Quote
  #4  
Old 03-09-2020, 02:18 PM
agermano agermano is offline
Mirth Guru
 
Join Date: Apr 2017
Location: Indiana, USA
Posts: 1,170
agermano is on a distinguished road
Default

FYI, the "proper" way to iterate over the keySet (or anything that implements the Java Iterable or Iterator interfaces) would be

Code:
for (var metaDataId in Iterator(message.getConnectorMessages().keySet())) {
    // ...
}
While they work most of the time, for each..in loops are actually part of e4x and meant for XMLLists. Most javascript engines won't even recognize the syntax. I say most of the time, because both for each..in and for..in loops are not designed to operate on arrays (which are really specialized objects.) If you assign values to other array properties besides their indexes, those values will be iterated over as well.

You could also skip the string conversion and put the Statuses directly in the array. If you were to do that, destinationStatus.indexOf(Status.SENT) would work.

If you wanted to make the solution a little more javascripty (is that a word?) you could do something like this (I'm assuming in 3.8.1 that you have ES6 mode enabled for the arrow functions to work):
Code:
var destinationStatus = message.connectorMessages.entrySet().toArray()
    .filter(e => e.key > 0)
    .map(e => e.value.responseData.status);
There are also alternatives to indexOf if you are just testing for the presense of a Status.

Code:
var atLeastOneSent = destinationStatus.some(s => s == Status.SENT);
var allERROR = destinationStatus.every(s => s == Status.ERROR);
Of course, you could also add the status to your filter and operate only on those connectors that match the desired status.
Code:
// log the status message for each destination connector with an ERROR status
message.connectorMessages.values().toArray()
    .filter(cm => cm.metaDataId > 0 && cm.responseData.status == Status.ERROR)
    .forEach(cm => {
        logger.info(cm.responseData.statusMessage);
    });
Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -8. The time now is 07:15 PM.


Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2020, vBulletin Solutions, Inc.
Mirth Corporation