Why is this happening?

Does anyone know why the following javascript code is triggering the warn alert?

function send(message) {
    if (
        message.measurement == null || message.measurement == ""
        || message.topic == null || message.topic == ""
        || message.payload == null || message.payload == ""
        ) {
        // node.warn("Invalid measurement: " + message.output + " - " + msg.topic + " / " + message.topic + " / " + message.measurement + " / " + message.payload);
        node.warn(message);
        return null;
    }
    node.send(message);
}

if (msg.topic.endsWith("/Status01")) {
    // const pumpState = flow.get("pumpState") || "";
    const pumpState = msg.payload["5"].value;
    const val0 = ((pumpState == "hwc" || pumpState == "off") ? 0 : msg.payload["0"].value);
    const val1 = ((pumpState == "hwc" || pumpState == "off") ? 0 : msg.payload["1"].value);
    const val3 = ((pumpState == "hwc") ? msg.payload["0"].value : 0);
    const val4 = ((pumpState == "hwc") ? msg.payload["1"].value : 0);

    send(
        {
            output: 11,
            measurement: "hvac_value",
            measurementType: "temperature",
            topic: "ebusd_" + ta[1] + "_z1FlowOutletTemp",
            payload: val0
        }
    );
    send(
        {
            output: 12,
            measurement: "hvac_value",
            measurementType: "temperature",
            topic: "ebusd_" + ta[1] + "_z1FlowInletTemp",
            payload: val1
        }
    );

    send(
        {
            output: 13,
            measurement: "hvac_value",
            measurementType: "temperature",
            topic: "ebusd_" + ta[1] + "_HwcFlowOutletTemp",
            payload: val3
        }
    );
    send(
        {
            output: 14,
            measurement: "hvac_value",
            measurementType: "temperature",
            topic: "ebusd_" + ta[1] + "_HwcFlowInletTemp",
            payload: val4
        }
    );
}

It just keeps printing those messages, but I see nothing wrong on them:

{
  "output": 11,
  "measurement": "hvac_value",
  "measurementType": "temperature",
  "topic": "ebusd_full_z1FlowOutletTemp",
  "payload": 0
}

{
  "output": 12,
  "measurement": "hvac_value",
  "measurementType": "temperature",
  "topic": "ebusd_full_z1FlowInletTemp",
  "payload": 0
}

{
  "output": 13,
  "measurement": "hvac_value",
  "measurementType": "temperature",
  "topic": "ebusd_full_HwcFlowOutletTemp",
  "payload": 0
}

{
  "output": 14,
  "measurement": "hvac_value",
  "measurementType": "temperature",
  "topic": "ebusd_full_HwcFlowInletTemp",
  "payload": 0
}

It started when I added the inline condition on the payloads.

You set message. payload to 0, which is falsey so your message.payload == null which returns true when payload is 0. Try message.payload === null or !message.payload

I think it is actually the message.payload == "" that is passing. That should be message.payload === "". An empty string is considered false in a test unless you use ===.

I ran the code with == "" and there was no warning received by the debug, when payload is 0. it only goes to warn if payload == null is there. You are correct the "" is falsey, but this is not causing the issue but may in future so it is best to use === Scratch that, error in payload when testing.

Seems that @Colin is on the right path, because the following code seems to work:

if (
    message.measurement === null || message.measurement === ""
    || message.topic === null || message.topic === ""
    || message.payload === null || message.payload === ""
    ) {

But I still don't understand what is going on. What I need if to check that all those properties are present, and they have values in them. The first two ones as string. Payload could be a number, or string, but never empty or null.

EDIT: I finally left it as:

!m.hasOwnProperty("measurement") || m.measurement === ""
|| !m.hasOwnProperty("topic") || m.topic === ""
|| !m.hasOwnProperty("payload") || m.payload === ""

Thnk you very much, pals.

That is odd, what does this do for you?
I see the empty string message.

[{"id":"782815a7e9524b3b","type":"inject","z":"bdd7be38.d3b55","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"0","payloadType":"num","x":190,"y":1940,"wires":[["9996d634bdca508f"]]},{"id":"9996d634bdca508f","type":"function","z":"bdd7be38.d3b55","name":"function 4","func":"if (msg.payload == null /*|| msg.payload == \"\"*/) {\n    node.warn(\"payload == null\")\n} if (/*msg.payload == null ||*/ msg.payload == \"\") {\n    node.warn(\"payload == empty string\")\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":340,"y":1940,"wires":[[]]}]

Never mind i had a payload value wrong in test, which through things out.

The problem is due to the fact that if you compare items of different types using == then javascript converts them separately to true or false values before running the test. So in the case where message.payload contains the number 0, and you compare it to an empty string then it converts 0 to false, and also the empty string is converted to false, so the test passes. If you use === you are telling javascript that you want them to be exactly equal, and since 0 and "" are of different types it says they are not equal.

1 Like

The problem is that there are a lot of tests to do to ensure a valid value arrives to the DB.
That the property exists.
That it doesn't contain an undefined value.
That contains a valid value (not string.empty for strings and not IsNaN for numbers).

I don't understand the relevance of your comment. I was explaining why you need === rather than == in this case.

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