javascriptnode-red

Accessing sub-fields of msg.payload using variables in Node-RED


I can access mqttData = msg.payload.Sum.Thin;.

I want Sum.Thin to be variable (it could be something else, like Data.Count).

This variable ('payloadConfig') is read as a string from a txt file.

I have tried all sorts of "tricks":

    // var payloadConfigObj = { payloadConfig };
    // var payloadConfigObj = new String(payloadConfig);
    var payloadConfigObj = JSON.stringify(payloadConfig);
    node.warn('payloadConfigObj: ' + JSON.stringify(payloadConfigObj) + ', type: ' + typeof (payloadConfigObj));

    // var jsonStr = payloadConfig.replace(/(\w+:)|(\w+ :)/g, function (matchedStr) {
        // return '"' + matchedStr.substring(0, matchedStr.length - 1) + '":';
    // });
    // payloadConfig = JSON.parse(jsonStr); //converts to a regular object


    // object payloadConfigObj = payloadConfig;
    // var payloadConfigObj = eval('({' + payloadConfig + '})');
    // var payloadConfigObj = Object.fromEntries(payloadConfig.split(',').map(i => i.split(':')));
    // const payloadConfigObj = payloadConfig.split('').map(letter => ({ letter: letter }));

    // var payloadConfigObj = JSON.parse(payloadConfig);    BROKE!

    // var payloadConfigObj = {};

    // mqttData = mqttPayload.payloadConfig;
    // mqttData = mqttPayload[payloadConfig];
    // mqttData = mqttPayload[{payloadConfig}];
    // mqttData = mqttPayload.indexOf(payloadConfig);
    // mqttData = mqttPayload['payloadConfig'];
    // mqttData = mqttPayload["payloadConfig"];

    // mqttData = mqttPayload.payloadConfigObj;
    // mqttData = mqttPayload[payloadConfigObj];
    // mqttData = mqttPayload['payloadConfigObj'];
    mqttData = mqttPayload["payloadConfigObj"];

Thanks https://stackoverflow.com/users/504554/hardillb! The problem was because I didn't seperate out the '.' elements (and still don't have to with the second method). Both methods worked well! https://stackoverflow.com/a/77911872/5165135

var payloadConfig1 = "Sum";
var payloadConfig2 = "Thin";
mqttData = msg.payload[payloadConfig1][payloadConfig2];

var payloadConfig = "Sum.Thin";
mqttData = RED.util.getObjectProperty(msg.payload, payloadConfig)

Unfortunately, when I added this to my code, Node-RED crashes. It works if I uncomment payloadConfig = "Sum.Thin"; I'm using

lineReader.on('line', function (line) {
            while (line.includes('\t\t')) {  /// Replace multiple tabs with single tab.
            line = line.replace(/\t\t/gi, '\t');
        }
        linesSplit = line.split('\t');
        var payloadConfig       = linesSplit[7];
        // payloadConfig = "Sum.Thin";
        try {
            mqttData = RED.util.getObjectProperty(mqttPayload, payloadConfig);
        }
        finally {
            node.error("Fail!");
        }
}

I don't understand as, Uncommented: "payloadConfig: Sum.Thin, type: string, mqttData: null" Commented: "payloadConfig: Sum.Thin, type: string, mqttData: null"


Solution

  • You need to split payloadConfig on the . and use square bracket notation for each part.

    E.g.

    msg.payload["data"]["count"]
    

    There is a helper function that can be used to do this for you RED.util.getObjectProperty()

    mqttData = RED.util.getObjectProperty(mqttPayload, payloadConfig)