Announcement

Collapse
No announcement yet.

Enum Status and inherited method toString() not working

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • 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: [email protected]).

    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!

  • #2
    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());

    Comment


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

      Adjusted to your second suggestion and works like a charm!

      Comment


      • #4
        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);
            });

        Comment

        Working...
        X