UI builder shows only variable name and not the value

Hi everyone!

I tried to make the following "Game Timer and Clue Display" in node-red, following this tutorial: Game Timer and Clue Display · playfultechnology/node-redscape Wiki · GitHub

I am able to change the background picture and to set a sound notification, but the main issue is that the time and hints are only displayed by the variable name, i.e. {{msg.timerText}} and {{msg.clueText}} instead of their actual value (see picture below). How can I fix this?

Any help will be MUCH appreciated as I have tried to fix this for countless hours by now...
Link to my flow (didn't change much from the original):

[
{
"id": "614ddf191ae89a8a",
"type": "tab",
"label": "Escape Room",
"disabled": false,
"info": "",
"env": []
},
{
"id": "3b61bfa4b5a01bad",
"type": "comment",
"z": "614ddf191ae89a8a",
"name": "Convert ms into hh:mm:ss",
"info": "",
"x": 710,
"y": 220,
"wires": []
},
{
"id": "7ba28fe8e8bd9765",
"type": "comment",
"z": "614ddf191ae89a8a",
"name": "Calculate time elapsed (or time remaining)",
"info": "",
"x": 400,
"y": 220,
"wires": [],
"icon": "node-red/parser-html.svg"
},
{
"id": "2ba4e18b445d4dd2",
"type": "uibuilder",
"z": "614ddf191ae89a8a",
"name": "Game Timer and Clue Display",
"topic": "",
"url": "timer_clue_display",
"fwdInMessages": false,
"allowScripts": true,
"allowStyles": true,
"copyIndex": true,
"templateFolder": "blank",
"extTemplate": "",
"showfolder": false,
"useSecurity": false,
"sessionLength": "",
"tokenAutoExtend": false,
"reload": false,
"sourceFolder": "src",
"x": 1290,
"y": 360,
"wires": [
[],
[]
]
},
{
"id": "19898d0278385d21",
"type": "inject",
"z": "614ddf191ae89a8a",
"name": "Every 1 sec",
"repeat": "1",
"crontab": "",
"once": true,
"onceDelay": "",
"topic": "",
"payload": "",
"payloadType": "date",
"x": 130,
"y": 260,
"wires": [
[
"78cff886443ac0d2"
]
]
},
{
"id": "c719d55547411130",
"type": "inject",
"z": "614ddf191ae89a8a",
"name": "",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "Here's a clue!",
"payloadType": "str",
"x": 130,
"y": 460,
"wires": [
[
"51914f8e439c2bd6",
"67d85c7cac21499b"
]
]
},
{
"id": "8d72eb1c2a04f761",
"type": "comment",
"z": "614ddf191ae89a8a",
"name": "Trigger",
"info": "",
"x": 150,
"y": 220,
"wires": [],
"icon": "node-red/parser-html.svg"
},
{
"id": "b731fdf7dbfb025f",
"type": "ui_audio",
"z": "614ddf191ae89a8a",
"name": "",
"group": "afbc44fd.ff57c8",
"voice": "",
"always": true,
"x": 780,
"y": 580,
"wires": []
},
{
"id": "67d85c7cac21499b",
"type": "file in",
"z": "614ddf191ae89a8a",
"name": "",
"filename": "C:\\Users\\Magnus Bessing\\.node-red/lydeffekt.mp3",
"format": "",
"chunk": false,
"sendError": false,
"encoding": "none",
"allProps": false,
"x": 478,
"y": 560,
"wires": [
[
"b731fdf7dbfb025f"
]
]
},
{
"id": "78cff886443ac0d2",
"type": "function",
"z": "614ddf191ae89a8a",
"name": "Update Game Timer",
"func": "// The current timestamp is injected at the start of the flow\nvar currentTime = msg.payload;\n\n// If this is the first time the flow has run, set the start time\nif(flow.get(\"startTime\") === undefined) {\n flow.set(\"startTime\", currentTime);\n}\nvar startTime = flow.get(\"startTime\");\n\n// Calculate the time elapsed since the flow started\nvar elapsedTime = (currentTime - startTime);\n\n// Update the msg to carry time elapsed \nmsg.time = elapsedTime;\n// Or, time remaining\nmsg.time = 3600000 - elapsedTime;\n\n// Display value in the editor\nnode.status({fill:\"green\",shape:\"dot\",text:elapsedTime});\n\n// Pass value along the flow\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 400,
"y": 260,
"wires": [
[
"0f4dd8a9cd384296"
]
]
},
{
"id": "0f4dd8a9cd384296",
"type": "function",
"z": "614ddf191ae89a8a",
"name": "Format Time As HH:MM:SS",
"func": "// msg.time is in milliseconds\nvar t = msg.time / 1000;\nvar h = Math.floor(t / 3600);\nvar m = Math.floor(t % 3600 / 60);\nvar s = Math.floor(t % 3600 % 60);\n\n// Format into hh:mm:ss\nmsg.timerText = (\"0\" + h).slice(-2) + \":\" + (\"0\" + m).slice(-2) + \":\" + (\"0\" + s).slice(-2);\n\n// Update the editor node\nnode.status({fill:\"green\", shape:\"dot\", text:msg.timerText});\n\n// Forward the message along the flow\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 700,
"y": 260,
"wires": [
[
"757b1e4b735f5898"
]
]
},
{
"id": "bfa2a7bb18315c8f",
"type": "comment",
"z": "614ddf191ae89a8a",
"name": "Display on ui builder page",
"info": "",
"x": 1250,
"y": 320,
"wires": []
},
{
"id": "51914f8e439c2bd6",
"type": "trigger",
"z": "614ddf191ae89a8a",
"name": "",
"op1": "",
"op2": " ",
"op1type": "pay",
"op2type": "str",
"duration": "10",
"extend": false,
"overrideDelay": false,
"units": "s",
"reset": "",
"bytopic": "all",
"topic": "topic",
"outputs": 1,
"x": 410,
"y": 460,
"wires": [
[
"3ce749af4de669b7"
]
]
},
{
"id": "3ce749af4de669b7",
"type": "change",
"z": "614ddf191ae89a8a",
"name": "",
"rules": [
{
"t": "set",
"p": "clueText",
"pt": "msg",
"to": "payload",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 730,
"y": 460,
"wires": [
[
"757b1e4b735f5898"
]
]
},
{
"id": "757b1e4b735f5898",
"type": "join",
"z": "614ddf191ae89a8a",
"name": "",
"mode": "custom",
"build": "merged",
"property": "",
"propertyType": "full",
"key": "topic",
"joiner": "\\n",
"joinerType": "str",
"accumulate": true,
"timeout": "",
"count": "1",
"reduceRight": false,
"reduceExp": "",
"reduceInit": "",
"reduceInitType": "num",
"reduceFixup": "",
"x": 1010,
"y": 360,
"wires": [
[
"2ba4e18b445d4dd2"
]
]
},
{
"id": "9267f0b913b59480",
"type": "comment",
"z": "614ddf191ae89a8a",
"name": "How long to display clue before clearing",
"info": "",
"x": 430,
"y": 420,
"wires": []
},
{
"id": "889e1d50da175f74",
"type": "comment",
"z": "614ddf191ae89a8a",
"name": "Combine time + clue",
"info": "",
"x": 1010,
"y": 320,
"wires": []
},
{
"id": "922270e4cf4d52c1",
"type": "comment",
"z": "614ddf191ae89a8a",
"name": "Set clue text",
"info": "",
"x": 130,
"y": 420,
"wires": [],
"icon": "node-red/parser-html.svg"
},
{
"id": "f62b7b0e96068337",
"type": "comment",
"z": "614ddf191ae89a8a",
"name": "Set msg variable",
"info": "",
"x": 720,
"y": 420,
"wires": []
},
{
"id": "9098bee38e6b9abd",
"type": "comment",
"z": "614ddf191ae89a8a",
"name": "Select SFX to play when clue displayed",
"info": "",
"x": 450,
"y": 520,
"wires": []
},
{
"id": "0aaff4405e858ac8",
"type": "comment",
"z": "614ddf191ae89a8a",
"name": "Send to audio output",
"info": "",
"x": 740,
"y": 520,
"wires": []
},
{
"id": "c47ac5a73dc0dcdc",
"type": "ui_button",
"z": "614ddf191ae89a8a",
"name": "",
"group": "afbc44fd.ff57c8",
"order": 1,
"width": 0,
"height": 0,
"passthru": false,
"label": "button",
"tooltip": "",
"color": "",
"bgcolor": "",
"className": "",
"icon": "",
"payload": "",
"payloadType": "str",
"topic": "topic",
"topicType": "msg",
"x": 110,
"y": 540,
"wires": [
[]
]
},
{
"id": "afbc44fd.ff57c8",
"type": "ui_group",
"name": "Hints",
"tab": "1c294719.eeb109",
"order": 2,
"disp": false,
"width": "10",
"collapse": false
},
{
"id": "1c294719.eeb109",
"type": "ui_tab",
"name": "Home",
"icon": "dashboard",
"disabled": false,
"hidden": false
}
]

Hmm, not sure what happened - I put in a reply but it disappeared. Here it is again.

What you are seeing means that VueJS isn't processing the page or at least the parts of the page with your dynamic settings.

Firstly, please make sure you aren't seeing any errors on the page by looking at the Console in the browser dev tools.

Then make sure that your dynamic areas are all inside the app element as shown in the example you gave:

    <div id="app">
        <!-- Dynamic elements will work here ... -->
        <div class="timerText">{{msg.timerText}}</div>
        <div class="clueText">{{msg.clueText}}</div>
    </div>
    <!-- ... but they wont work here -->

Thanks for your reply, Julian!

I get the following error messages when inspecting the console:
error

I'm not very familiar with HTML, but I believe I have no additional dynamics other than timerText and clueText. Do you know why the VueJS may not be processing the page? It says it is not defined, how do I do that?

/Magnus

The status code 404 is the HTTP standard status for "Not Found". Which is why nothing is working for you.

Did you install vue using uibuilder's library manager?

If you haven't already done that, there is a slight hicup because VueJS have changed their default install. Now you will need to use the command line on your Node-RED server and ...

Assuming that you are using the current version of uibuilder (4.1.4) and have Node-RED installed in the usual way:

cd ~/.node-red
npm install vue@2

If you don't have easy access to the server's command line, you can add a trigger node connected to an exec node. In the exec node put the command:

cd /home/pi/.node-red && npm install vue@2

That assumes that you are using a raspberry pi with a standard setup - if not, you will need to adjust the cd command. The node-red log tells you the location of the "User directory" on startup which is what you want.

This problem will be resolved when v5 is released.

I installed it inside the ui node, by clicking "Manage front-end libraries" and then adding it, like this:
vue

I installed node-red locally, and just tried to install vue manually, putting your command in the cmd. I now get this:

Still not quite working, but a different error...

OK, can you share your index.html file?

You are still not managing to load the library.

Sure, I copied it from the tutorial and didn't change it afterwards. It looks like this:

<!doctype html>
<html lang="en">
<head>
    <!-- Put your own custom styles in here -->
    <link rel="stylesheet" href="./index.css" media="all">
    <!-- Include Webfont to style text in custom font -->
    <link href="https://fonts.googleapis.com/css?family=Staatliches&display=swap" rel="stylesheet"> 
</head>
<body>
    <!-- The "app" element contains any content that receives dynamic updates -->
    <div id="app">
        <div class="timerText">{{msg.timerText}}</div>
        <div class="clueText">{{msg.clueText}}</div>
    </div>
    <!-- uibuilder script libraries -->
    <script src="../uibuilder/vendor/socket.io/socket.io.js"></script>
    <script src="../uibuilder/vendor/vue/dist/vue.min.js"></script>
    <script src="./uibuilderfe.min.js"></script>
    <!-- Put any additional custom code in here -->
    <script src="./index.js"></script>
</body>
</html>

Can you check what version of vue you installed?

Nevermind, I installed the wrong adress - corrected it, and it now works! Wierd it had to be installed manually though- still don't quite understand why that's the case.

Thank you very much, Julian!

So, going forward I created a Cloud Foundry App with IBM Cloud from which I run Node-Red. Everything works, except for this very same problem again (VueJS isn't processing the page). I'm not sure if I can access a command line or how else I would be able to install it. Is there a work around? Thanks!

Can you see the node-red log? If so, it tells you the userDir folder which you need to know.

Once you have that, you may be able to use an exec node.

cd /absolute/folder/userdir/ && npm install vue@2

Hmm, I don't think I am able to see the node-red log. Nothing is local currently, everything is run by IBM cloud.

I'd be surprised if you couldn't access the log somehow. I don't use the IBM cloud so I can't really help with that. Maybe asking a specific question in the forum might get an answer from someone who does?

There isn't much point in running a service on a cloud platform if you can't see its logs since you would never be able to do any troubleshooting.

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