Problem with string.includes inside a function node

I have a function where I read a series of OPC-UA nodes from a machine. The OPC-UA node returns a message where msg.payload is an array of objects where the value, type of the variable and the timestamp are located.

It also returns an msg.items array of the same size where the nodeID for each OPC-UA tag is located.

Now, OPC-UA nodeIDs are NOT human readable and have special characters, which can be a mess if I want to combine all the tags and their values as key/value pairs in a single object.

My thinking was to first go through the items array and add a field with the variable name to each cell, something like this:

var i = 0;
var lengthItems = msg.items.length;
var tmpStr = "";

for (i=0; i<lengthItems;i++){
    tmpStr = msg.items[i].nodeId;
    if (tmpStr.includes("M01MA01MH01#0_E_B")){
        msg.items[i].varName = "machine_started";
    } else if (tmpStr.includes("M01SE01MG01#0_E_B")) {
        msg.items[i].varName = "m01_full";
    } else if (tmpStr.includes("M01SE01MH14#0_BA_B")) {
        msg.items[i].varName = "m01_jam";
    } else if (tmpStr.includes("M01SE01MN05#1_X_DW")) {
        msg.items[i].varName = "machine_abs_count";
    } else if (tmpStr.includes("M01SE01MN05#0_X_DW")) {
        msg.items[i].varName = "machine_rel_count";
    } else if (tmpStr.includes("M01SE01GH01#0_BA_Y")) {
        msg.items[i].varName = "machine_speed_set";
    } else if (tmpStr.includes("M01SE01GH01#0_E_B")) {
        msg.items[i].varName = "machine_conv_enabled";
    } else if (tmpStr.includes("M01SE01MS02#0_W_I")) {
        msg.items[i].varName = "machine_speed_actual";
    } else if (tmpStr.includes("M01SE01MS02#0_OW_I")) {
        msg.items[i].varName = "machine_speed_delta_warning";
    } else if (tmpStr.includes("M01SE01MS02#0_OG_I")) {
        msg.items[i].varName = "machine_speed_delta_alarm";
    } else if (tmpStr.includes("M01SE01MY13#0_E_B")) {
        msg.items[i].varName = "machine_standby";
    } else {
        msg.items[i].varName = "not defined";
    }
        
}

return msg;

I thought the string.includes() is a basic string function, and even the monaco editor prompts me with the right syntax when I start writing it, but when I try to run it, I get the following error:
image

Any thoughts about why it is not working?

I would add some logging to check that msg.items[i].nodeId always exists - maybe for some edge case it isn't being returned or set as a String.

I would also double check it really is a string - or see what typeof tmpStr returns. The OPCUA node might be returning a custom object that looks a lot like a String, but isn't really one.

Since I knew msg.items[i].nodeID always exists, I skipped that logging part.

I assumed that what you said was true, that the type was wrong, so I modified the code when I assigned the value to tmpStr to force a type conversion:

var i = 0;
var lengthItems = msg.items.length;
var tmpStr = "";

for (i=0; i<lengthItems;i++){
    tmpStr = String(msg.items[i].nodeId);
    if (tmpStr.includes("M01MA01MH01#0_E_B")){
        msg.items[i].varName = "machine_started";
    } else if (tmpStr.includes("M01SE01MG01#0_E_B")) {
        msg.items[i].varName = "m01_full";
    } else if (tmpStr.includes("M01SE01MH14#0_BA_B")) {
        msg.items[i].varName = "m01_jam";
    } else if (tmpStr.includes("M01SE01MN05#1_X_DW")) {
        msg.items[i].varName = "machine_abs_count";
    } else if (tmpStr.includes("M01SE01MN05#0_X_DW")) {
        msg.items[i].varName = "machine_rel_count";
    } else if (tmpStr.includes("M01SE01GH01#0_BA_Y")) {
        msg.items[i].varName = "machine_speed_set";
    } else if (tmpStr.includes("M01SE01GH01#0_E_B")) {
        msg.items[i].varName = "machine_conv_enabled";
    } else if (tmpStr.includes("M01SE01MS02#0_W_I")) {
        msg.items[i].varName = "machine_speed_actual";
    } else if (tmpStr.includes("M01SE01MS02#0_OW_I")) {
        msg.items[i].varName = "machine_speed_delta_warning";
    } else if (tmpStr.includes("M01SE01MS02#0_OG_I")) {
        msg.items[i].varName = "machine_speed_delta_alarm";
    } else if (tmpStr.includes("M01SE01MY13#0_E_B")) {
        msg.items[i].varName = "machine_standby";
    } else {
        msg.items[i].varName = "not defined";
    }
        
}

return msg;

Now it's working like a charm, so I assume that was the problem. What it is extremely strange is that if I used the String node it would work, so I can only assume the String node forces any input type into strings before any manipulation.

That will show me not to assume anything. Damn, and here I thought C's loose policy with types was dirty.

Thank you very much for the help!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.