Template Node: Multiple debug messages after each restart

I am just using the default code in the UI template node for Dashboard 2.0. I noticed that each time I redeploy or restart the flow an additional debug message is written to the debug window. If I restart it 10 times I get 10 debug messages for one debug instance. Closing the dashboard browser page and reopening it sets the number of debug messages back to 1. Until I redeploy or restart. This is a screen capture of what I am talking about.

Thanks @daveo - very odd, I’ll take a proper look in the morning

Let me add: it seems that the new implementation of the send() command in v1.0.0 is sending multiple copies of the output msg (the number of copies increases after every send).
It is also worth mentioning in the documentation, that this.send() does not work from within the socket listener, and the scope needs to be saved in an external variable.

Consider the following simple flow:
image

The JavaScript code in the template is:

<script>
var $scope = this;
this.$socket.on('msg-input:' + this.id, function(msg) {
    $scope.send('Forwarding payload '+msg.payload);
});
</script>

I inject once, and the output is:


where the number of replicas grows after every inject

Thanks @omrid - on it this morning, making it a priority to fix

1 Like

PR is going in now - UI Template: Ensure "widget-send" events are cleared on socket connection loss by joepavitt · Pull Request #525 · FlowFuse/node-red-dashboard · GitHub should be live in v1.0.1 in the next 30 minutes

1 Like

Hi Joe, thanks for the quick turnaround!
Problem is still not fully solved,(maybe I am doing something wrong?).
The inject node still forces multiple output replications. Same happens when I send the message from a ui-button.
However, when the msg in initiated by an internal event and not through the socket listener (e.g. clicking a button defined with HTML inside the template), the output comes out once, as it should.

image
The ui-template code:

<template>
<button class="button-class" onClick="onClick()">Raw Button</button>
</template>

<script>
var $scope = this;
this.$socket.on('msg-input:' + this.id, function(msg) {
    $scope.send('Forwarding payload '+msg.payload);
});
window.onClick = function() {
    $scope.send('msg sent from internal button');
}
</script>

The output:
image

Do you have “Pass through messages from input” still enabled for the ui-template? If so, I’d expect to see 2 x messages here, as the ui-template under the covers will pass on the message (because it’s been told to by it’s config), and then you’re adding an extra listener for msg-input here in the ui-template itself?

First thing I checked… passthrough is disabled. The passthrough msg is different (does not have the “forwarded” tag), when I enable passthrough the original msg comes in addition as it should. BTW, sometimes I get 4 outgoing messages for a single inject.

Are you able to simulate this odd behavior on your environment?

yep - okay, I’m seeing it after a restart of Node-RED.

Thanks for finding this @omrid - solution going live now with this PR: UI Template - Ensure client-side events are turned off for msg-input by joepavitt · Pull Request #529 · FlowFuse/node-red-dashboard · GitHub

v1.0.2 should be available in Palette Manager in next 30 mins.

All working perfectly now. Thanks Joe for the quick turnaround!

Since I also got confused on this at first, it’s worth noting how the dashboard works in multi-user scenario.
When multiple clients show the same dashboard page, clicking a button, switch etc. in any of the clients, invokes a single message. If the button was connected to a “server” node (e.g. debug node), the message will appear once.
However, if the button is connected to another dashboard node (e.g. template) on the same page, it is not really a direct connection. The button-click message is sent to the server and then rebounded to all the clients, so each template instance receives a copy of the message (and if the template instances react and send something, it may appear as if one of them sent multiple messages).
To limit a template node to handle only messages coming from dashboard nodes of its own page, you need to filter by socketId, for example:

var $scope = this;
this.$socket.on('msg-input:' + this.id, function(msg) {
    if (msg.hasOwnProperty("_client") && msg._client.socketId === $scope.$socket.id)
      // msg invoked from this client
    else
     // msg invoked from server node or from another client
});