Send MSG back to NR from Dashboard 2.0 template node

Hi there,

I'm currently working with NR 4.0.2 and @flowfuse/node-red-dashboard:1.16.0

I'm aiming to have a button in a template node that sends back a msg.payload when I click it. Following the documentation DOC , I used this.send() function to pass on data back into Node-RED.

However I must be missing something because I recieve the data when this.send is directly on the script (page's first load), but when it's inside an event listener, the browser's console returns that send is not defined.

I leave here the code im using so you can test it:

Flow

[
    {
        "id": "722d8da36de071df",
        "type": "ui-template",
        "z": "f6f2187d.f17ca8",
        "group": "71a95203ce9df61e",
        "page": "",
        "ui": "",
        "name": "Button",
        "order": 1,
        "width": "6",
        "height": "4",
        "head": "",
        "format": "<template>\n    <button id=\"test-btn\" class=\"test-btn\" >My Button</button>\n</template>\n\n<script>\n    document.getElementById(\"test-btn\").addEventListener(\"click\", function() {\n        var data1 = \"AA\";\n        var data2 = \"BB-1\";\n        var msg = {payload: {'data1': data1, 'data2': data2}};\n        this.send(msg);\n    });\n    this.send('ScriptOn');\n</script>\n\n<style>\n    /* define any styles here - supports raw CSS */\n    .test-btn {\n        background-color: #f54;\n        color: white;\n        border: none;\n        padding: 10px;\n        border-radius: 5px;\n        cursor: pointer;\n    }\n</style>",
        "storeOutMessages": true,
        "passthru": true,
        "resendOnRefresh": true,
        "templateScope": "local",
        "className": "",
        "x": 178,
        "y": 424,
        "wires": [
            [
                "fd077dd87df6d242"
            ]
        ]
    },
    {
        "id": "fd077dd87df6d242",
        "type": "debug",
        "z": "f6f2187d.f17ca8",
        "name": "debug 2",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 428,
        "y": 424,
        "wires": []
    },
    {
        "id": "71a95203ce9df61e",
        "type": "ui-group",
        "name": "Group Name",
        "page": "9ef10008cf9bd85d",
        "width": "6",
        "height": "1",
        "order": 1,
        "showTitle": true,
        "className": "",
        "visible": "true",
        "disabled": "false"
    },
    {
        "id": "9ef10008cf9bd85d",
        "type": "ui-page",
        "name": "TEST",
        "ui": "99b0f7213609f95f",
        "path": "/page3",
        "icon": "home",
        "layout": "grid",
        "theme": "7595dc06ddd9d219",
        "order": 4,
        "className": "",
        "visible": "true",
        "disabled": "false"
    },
    {
        "id": "99b0f7213609f95f",
        "type": "ui-base",
        "name": "MES",
        "path": "/dashboard",
        "includeClientData": true,
        "acceptsClientConfig": [
            "ui-notification",
            "ui-control"
        ],
        "showPathInSidebar": false,
        "showPageTitle": false,
        "navigationStyle": "none",
        "titleBarStyle": "hidden"
    },
    {
        "id": "7595dc06ddd9d219",
        "type": "ui-theme",
        "name": "MA_Theme",
        "colors": {
            "surface": "#bababa",
            "primary": "#e40521",
            "bgPage": "#111111",
            "groupBg": "#3c3c3b",
            "groupOutline": "#3c3c3b"
        },
        "sizes": {
            "density": "default",
            "pagePadding": "12px",
            "groupGap": "12px",
            "groupBorderRadius": "10px",
            "widgetGap": "12px"
        }
    }
]

Template content:

<template>
    <button id="test-btn" class="test-btn" >My Button</button>
</template>

<script>
    document.getElementById("test-btn").addEventListener("click", function() {
        var data1 = "AA";
        var data2 = "BB-1";
        var msg = {payload: {'data1': data1, 'data2': data2}};
        this.send(msg);
    });
    this.send('ScriptOn');
</script>

<style>
    /* define any styles here - supports raw CSS */
    .test-btn {
        background-color: #f54;
        color: white;
        border: none;
        padding: 10px;
        border-radius: 5px;
        cursor: pointer;
    }
</style>

Hope some of you could help me with that, thanks!

With JavaScript, if you use function () { } to define, well, a function, it creates a new scope, meaning that this. refers to your function definition, rather than it's parent scope (where the this.send() function is defined.

In this case, you'll just need to define it as an "anonymous" function:

    document.getElementById("test-btn").addEventListener("click", () => {
        var data1 = "AA";
        var data2 = "BB-1";
        var msg = {payload: {'data1': data1, 'data2': data2}};
        this.send(msg);
    });
    this.send('ScriptOn');
1 Like

To be on the safe side and not have worry about this, I always keep the template's this value in a variable, and use it.
for example:

<script>
const $scope = this;
...
$scope.send(msg);  //from anywhere in the script
...
</script>
2 Likes

Thanks, that was useful!

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