Errors with UI templates

I'm using this ui template to display some Grafana charts in an iframe.

The flow works OK, but on page refresh I see

TypeError: Cannot read properties of undefined (reading 'payload')

in browser console. Is there some way to stop this ?

My limited understanding tells me that scope watch shouldn't be trying to set the attribute until the payload arrives, so why the error on refresh or page load?

<html>
<iframe id="myFrame3"  width="1384" height="106px" style = "overflow:hidden; margin:auto; border:0px solid green;"></iframe>

<script>
//NOTE, more then one chart on a page, rename in the second and following 
//templates the "myframe" variable so that every template has a unique name.
(function(scope) {
    // watch msg object from Node-RED
    scope.$watch('msg', function(msg) {
        // new message received
        var x = document.getElementById('myFrame3');
        x.setAttribute('src', msg.payload); 
        });
})(scope);
</script>
</html>

hello .. have you unchecked the option in the ui_template

image

Yes tried all combinations ?

what if you console.log the msg in $watch to see for any clues in the browser's dev tools, where that msg is coming from

scope.$watch('msg', function(msg) {
        // new message received
        console.log(msg)
        var x = document.getElementById('myFrame3');
        x.setAttribute('src', msg.payload); 
        });

good idea but it shows nothing in log :sleepy:
scratch that it was filter in console, I do get an undefined msg, even if the ui-node has no input connected :crazy_face:

If I disable the ui-template error goes away so it must be from that node.

Does it run the function on a page refresh, and even without a payload excute
x.setAttribute('src', msg.payload); one time ?

Thanks for your help - it looks there is a phantom msg, I got around that with

if (msg != null) {x.setAttribute('src', msg.payload)};
1 Like

I tested your code and it does seem to execute everytime .. even with the Reload last value unchecked

maybe the best way to block it from proceeding is use an if statement like in the example in the help tab
to check if the msg has a value before proceeding

(function(scope) {
    // watch msg object from Node-RED
    scope.$watch('msg', function(msg) {
    if (msg) {
        // new message received
        var x = document.getElementById('myFrame3');
        x.setAttribute('src', msg.payload);
    }
    });
})(scope);
1 Like

Thanks for checking, I thought I was going mad :wink:

Looks like I need to do a lot of modifications in all my scope.$watch functions :rofl:

1 Like