Context store and array

Hello

I'm experiencing a strange behaviour when reading an array from the context store.
The array is altered in the context store just by reading it inside the function block.
Please can someone explain to me why this is happening.

I include a example flow:

[
    {
        "id": "aacefb7f.a06e28",
        "type": "inject",
        "z": "ab2e2a9e.27b058",
        "name": "Set Global var",
        "topic": "",
        "payload": "[{\"DowntimeCode\":\"DT009\",\"DownTimeL1\":\"OEE\",\"DownTimeL2\":\"Unplanned Stoppage\",\"DownTimeL3\":\"Parts Contaminated with Swarf\",\"DownTimeL4\":\"Parts Contaminated with Swarf\",\"AccessLevel\":\"1         \",\"Filter\":\"ALL\",\"Valid\":\"Y\",\"Rank\":1},{\"DowntimeCode\":\"DT038\",\"DownTimeL1\":\"OEE\",\"DownTimeL2\":\"Unplanned Stoppage\",\"DownTimeL3\":\"Part Jammed in the Feed Rail\",\"DownTimeL4\":\"Part Jammed in the Feed Rail\",\"AccessLevel\":\"1         \",\"Filter\":\"ALL\",\"Valid\":\"Y\",\"Rank\":2},{\"DowntimeCode\":\"DT039\",\"DownTimeL1\":\"OEE\",\"DownTimeL2\":\"Production rate Deviation\",\"DownTimeL3\":\"Mixed Parts\",\"DownTimeL4\":\"Mixed Parts\",\"AccessLevel\":\"1         \",\"Filter\":\"ALL\",\"Valid\":\"Y\",\"Rank\":2}]",
        "payloadType": "json",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "x": 210,
        "y": 520,
        "wires": [
            [
                "78d1f8f.b1c8308"
            ]
        ]
    },
    {
        "id": "78d1f8f.b1c8308",
        "type": "change",
        "z": "ab2e2a9e.27b058",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "dtcodeLV1",
                "pt": "global",
                "to": "payload",
                "tot": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 420,
        "y": 520,
        "wires": [
            []
        ]
    },
    {
        "id": "1cd8e8a0.25c0f7",
        "type": "inject",
        "z": "ab2e2a9e.27b058",
        "name": "Read Global var (this will break it)",
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "x": 270,
        "y": 580,
        "wires": [
            [
                "f4fb9963.0ef488"
            ]
        ]
    },
    {
        "id": "59a2ab43.265574",
        "type": "debug",
        "z": "ab2e2a9e.27b058",
        "name": "Altered Array in context store",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "x": 840,
        "y": 580,
        "wires": []
    },
    {
        "id": "f4fb9963.0ef488",
        "type": "function",
        "z": "ab2e2a9e.27b058",
        "name": "read array from context store",
        "func": "var arr = global.get('dtcodeLV1');\nreturn arr;",
        "outputs": 1,
        "noerr": 0,
        "x": 560,
        "y": 580,
        "wires": [
            [
                "59a2ab43.265574"
            ]
        ]
    },
    {
        "id": "bf6be241.7ad6",
        "type": "inject",
        "z": "ab2e2a9e.27b058",
        "name": "Read Global var (this works fine)",
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "x": 270,
        "y": 700,
        "wires": [
            [
                "a2cb83fc.c62ef"
            ]
        ]
    },
    {
        "id": "a2cb83fc.c62ef",
        "type": "change",
        "z": "ab2e2a9e.27b058",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "dtcodeLV1",
                "tot": "global"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 540,
        "y": 700,
        "wires": [
            [
                "dcad5382.3dcc3"
            ]
        ]
    },
    {
        "id": "dcad5382.3dcc3",
        "type": "debug",
        "z": "ab2e2a9e.27b058",
        "name": "Unchanged array context store",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "x": 850,
        "y": 700,
        "wires": []
    },
    {
        "id": "9dfed747.32b628",
        "type": "inject",
        "z": "ab2e2a9e.27b058",
        "name": "Read Global var (this works fine)",
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "x": 270,
        "y": 640,
        "wires": [
            [
                "537f7bd7.685914"
            ]
        ]
    },
    {
        "id": "25dc1cc6.ce4b04",
        "type": "debug",
        "z": "ab2e2a9e.27b058",
        "name": "Unchanged array in context store",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "x": 860,
        "y": 640,
        "wires": []
    },
    {
        "id": "537f7bd7.685914",
        "type": "function",
        "z": "ab2e2a9e.27b058",
        "name": "read array from context store",
        "func": "var arr = global.get('dtcodeLV1');\nmsg.payload = arr;\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 540,
        "y": 640,
        "wires": [
            [
                "25dc1cc6.ce4b04"
            ]
        ]
    }
]

In the function

var arr = global.get('dtcodeLV1');
return arr;

you are not returning an object but a pointer to an array. Change the function to

var arr = global.get('dtcodeLV1');
msg.payload = arr
return msg;

Hello

Thank you for your answer.

The question is why the structure of an array stored in the context store is altered after performing

Array before:

[{"DowntimeCode":"DT041","DownTimeL1":"OEE","DownTimeL2":"Unplanned Stoppage","DownTimeL3":"Operator Unavailable","DownTimeL4":"Cleaning Parts","AccessLevel":"2         ","Filter":"ALL","Valid":"Y","Rank":3},{"DowntimeCode":"DT007","DownTimeL1":"GOEE","DownTimeL2":"Planned Stoppage","DownTimeL3":"Operator Unavailable","DownTimeL4":"Operator Break","AccessLevel":"2         ","Filter":"ALL","Valid":"Y","Rank":7},{"DowntimeCode":"DT018","DownTimeL1":"OEE","DownTimeL2":"Unplanned Stoppage","DownTimeL3":"Breakdown","DownTimeL4":"Health and Safety","AccessLevel":"2         ","Filter":"ALL","Valid":"Y","Rank":13},{"DowntimeCode":"DT008","DownTimeL1":"GOEE","DownTimeL2":"Planned Stoppage","DownTimeL3":"Operator Unavailable","DownTimeL4":"Meeting / Briefing ","AccessLevel":"2         ","Filter":"ALL","Valid":"Y","Rank":18},{"DowntimeCode":"DT030","DownTimeL1":"OEE","DownTimeL2":"Unplanned Stoppage","DownTimeL3":"Smash Up","DownTimeL4":"Swarf","AccessLevel":"2         ","Filter":"ALL","Valid":"Y","Rank":19},{"DowntimeCode":"DT032","DownTimeL1":"OEE","DownTimeL2":"Production Rate Deviation","DownTimeL3":"Misfeed","DownTimeL4":"Swarf","AccessLevel":"2         ","Filter":"ALL","Valid":"Y","Rank":20},{"DowntimeCode":"DT025","DownTimeL1":"OEE","DownTimeL2":"WaitingTime","DownTimeL3":"Operator Unavailable","DownTimeL4":"Working on the other M/C","AccessLevel":"2         ","Filter":"ALL","Valid":"Y","Rank":22},{"DowntimeCode":"DT035","DownTimeL1":"OEE","DownTimeL2":"Production Rate Deviation","DownTimeL3":"Machine Adjustment","DownTimeL4":"Quality Issue","AccessLevel":"2         ","Filter":"ALL","Valid":"Y","Rank":23},{"DowntimeCode":"DT036","DownTimeL1":"OEE","DownTimeL2":"Production Rate Deviation","DownTimeL3":"Machine Adjustment","DownTimeL4":"Productivity Issue","AccessLevel":"2         ","Filter":"ALL","Valid":"Y","Rank":24},{"DowntimeCode":"DT019","DownTimeL1":"OEE","DownTimeL2":"Unplanned Stoppage","DownTimeL3":"Breakdown","DownTimeL4":"Mechanical","AccessLevel":"2         ","Filter":"ALL","Valid":"Y","Rank":25},{"DowntimeCode":"DT020","DownTimeL1":"OEE","DownTimeL2":"Unplanned Stoppage","DownTimeL3":"Breakdown","DownTimeL4":"Electrical","AccessLevel":"2         ","Filter":"ALL","Valid":"Y","Rank":26},{"DowntimeCode":"DT021","DownTimeL1":"OEE","DownTimeL2":"Unplanned Stoppage","DownTimeL3":"Breakdown","DownTimeL4":"Pneumatic","AccessLevel":"2         ","Filter":"ALL","Valid":"Y","Rank":27},{"DowntimeCode":"DT022","DownTimeL1":"OEE","DownTimeL2":"Unplanned Stoppage","DownTimeL3":"Breakdown","DownTimeL4":"Hydraulic","AccessLevel":"2         ","Filter":"ALL","Valid":"Y","Rank":28},{"DowntimeCode":"DT026","DownTimeL1":"OEE","DownTimeL2":"WaitingTime","DownTimeL3":"Operator Unavailable","DownTimeL4":"Helping Others","AccessLevel":"2         ","Filter":"ALL","Valid":"Y","Rank":29},{"DowntimeCode":"DT029","DownTimeL1":"OEE","DownTimeL2":"Unplanned Stoppage","DownTimeL3":"Smash Up","DownTimeL4":"Double Feed","AccessLevel":"2         ","Filter":"ALL","Valid":"Y","Rank":30},{"DowntimeCode":"DT033","DownTimeL1":"OEE","DownTimeL2":"Production Rate Deviation","DownTimeL3":"Misfeed","DownTimeL4":"Mixed Parts","AccessLevel":"2         ","Filter":"ALL","Valid":"Y","Rank":32},{"DowntimeCode":"DT028","DownTimeL1":"GOEE","DownTimeL2":"Planned Stoppage","DownTimeL3":"Operator Unavailable","DownTimeL4":"Unmanned Shift","AccessLevel":"2         ","Filter":"ALL","Valid":"Y","Rank":33},{"DowntimeCode":"DT027","DownTimeL1":"GOEE","DownTimeL2":"Planned Stoppage","DownTimeL3":"Operator Unavailable","DownTimeL4":"Training","AccessLevel":"2         ","Filter":"ALL","Valid":"Y","Rank":42},{"DowntimeCode":"DT012","DownTimeL1":"OEE","DownTimeL2":"Unplanned Stoppage","DownTimeL3":"Smash Up","DownTimeL4":"Mixed Parts","AccessLevel":"2         ","Filter":"ALL","Valid":"Y","Rank":42}]

to

[[{"DowntimeCode":"DT009","DownTimeL1":"OEE","DownTimeL2":"Unplanned Stoppage","DownTimeL3":"Parts Contaminated with Swarf","DownTimeL4":"Parts Contaminated with Swarf","AccessLevel":"1         ","Filter":"ALL","Valid":"Y","Rank":1,"_msgid":"6bab5b4b.37b4f4"}],[{"DowntimeCode":"DT038","DownTimeL1":"OEE","DownTimeL2":"Unplanned Stoppage","DownTimeL3":"Part Jammed in the Feed Rail","DownTimeL4":"Part Jammed in the Feed Rail","AccessLevel":"1         ","Filter":"ALL","Valid":"Y","Rank":2,"_msgid":"6bab5b4b.37b4f4"}],[{"DowntimeCode":"DT039","DownTimeL1":"OEE","DownTimeL2":"Production rate Deviation","DownTimeL3":"Mixed Parts","DownTimeL4":"Mixed Parts","AccessLevel":"1         ","Filter":"ALL","Valid":"Y","Rank":2,"_msgid":"6bab5b4b.37b4f4"}]]

after performing only

global.get('dtcodeLV1');

Please use an example flow from my first post to understand what I'm on about.

  1. Use Set Global var trigger to write var to the context.
  2. Check the structure of data stored in the context.
  3. Press Read Global var (this will break it)
  4. Check the structure of data stored in the context. The structure of an array is altered
  5. Use Set Global var trigger to write var to the context.
  6. Press Read Global var (this works fine)
  7. Check the structure of data stored in the context. The structure of an array is unchanged

In other words I know how to deal with it, but I don't understand this behavior.

It is not legal to return just an array, you should return it in a message as @zenofmud indicated. Because it is not a message node-red has attempted to convert it to a message by adding msg_id.

When you read from context you are getting a reference to the object held in context. If you modify it, you are modifying the object held in context.

If you want to modify it without modifying what is held in context, then you need to clone it.

Thank you all for the explanation.

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