Execute a flow when pages (URL) opens or refreshes

I have a webpage built with Ui-Builder, where i need to display data from sqlite.
Using the inject node i am able to see the data, eveytime i manually press the inject node.
Is there a way to remove this manual inject and do it automatically avery time the page open or is refreshed?

Hello .. Are you using Vue for you uibuilder page ?
Can you share your page code ?

No i regular javascript with .js file and HTML

There is an article here that shows an example of executing some code when the page loads

document.addEventListener("DOMContentLoaded", function () {
   uibuilder.send({payload: "send me the sqlite data"})
});

You don't need to do that, just connect to the 2nd output port of the uibuilder node. It outputs a msg whenever a client connects. You can use that to trigger a flow.

Try the example uibuilder caching flow (see the examples library in the node-red import menu). It uses the connect msg to trigger a replay of a cache for new clients.

uibuilder is there to help and to reduce the dependencies on low-level code and DOM events.

3 Likes

Still not able to to make it work. Works fine using the manual inject, does not works using the second output of the uibuilder.
See flow example ( crete table and insert values first)

[
    {
        "id": "eca378ab71489651",
        "type": "tab",
        "label": "Mypage",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "b995a5fc5fdc2ab0",
        "type": "inject",
        "z": "eca378ab71489651",
        "name": "Create tag table",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "CREATE TABLE tag(id_tag INTEGER,timestamp INTEGER,product)",
        "payload": "",
        "payloadType": "date",
        "x": 340,
        "y": 60,
        "wires": [
            [
                "8de2d42d36b38fad"
            ]
        ]
    },
    {
        "id": "8de2d42d36b38fad",
        "type": "sqlite",
        "z": "eca378ab71489651",
        "mydb": "78507d7a12077e6d",
        "sqlquery": "msg.topic",
        "sql": "",
        "name": "tagdb",
        "x": 570,
        "y": 80,
        "wires": [
            []
        ]
    },
    {
        "id": "dfcf7e56bc8bc0b9",
        "type": "inject",
        "z": "eca378ab71489651",
        "name": "Drop table",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "DROP TABLE tag",
        "payload": "",
        "payloadType": "date",
        "x": 320,
        "y": 100,
        "wires": [
            [
                "8de2d42d36b38fad"
            ]
        ]
    },
    {
        "id": "3cdc36c8472a44b6",
        "type": "comment",
        "z": "eca378ab71489651",
        "name": "Create table",
        "info": "",
        "x": 110,
        "y": 60,
        "wires": []
    },
    {
        "id": "e4068e01e607646f",
        "type": "comment",
        "z": "eca378ab71489651",
        "name": "Drop Table",
        "info": "",
        "x": 100,
        "y": 100,
        "wires": []
    },
    {
        "id": "97bdda09d42b53a5",
        "type": "inject",
        "z": "eca378ab71489651",
        "name": "Insert",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "INSERT INTO tag VALUES(1,1659430564,\"B\"),(2,1659430564,\"B\"),(2,1659430564,\"B\"),(4,1659430564,\"D\"),(2,1659430564,\"A\"),(2,1659430564,\"B\"),(2,1659430564,\"C\"),(2,1659430564,\"D\"),(1,1659430564,\"A\"),(3,1659430564,\"B\"),(2,1659430564,\"D\"),(1,1659430564,\"D\"),(1,1659430564,\"A\"),(3,1659430564,\"B\"),(1,1659430564,\"C\"),(1,1659430564,\"D\");",
        "payload": "",
        "payloadType": "date",
        "x": 310,
        "y": 140,
        "wires": [
            [
                "8de2d42d36b38fad"
            ]
        ]
    },
    {
        "id": "80cda4eae8b2ba05",
        "type": "comment",
        "z": "eca378ab71489651",
        "name": "insert Tags",
        "info": "",
        "x": 100,
        "y": 140,
        "wires": []
    },
    {
        "id": "bcf82d2f339ec188",
        "type": "uibuilder",
        "z": "eca378ab71489651",
        "name": "",
        "topic": "",
        "url": "tag",
        "fwdInMessages": false,
        "allowScripts": false,
        "allowStyles": false,
        "copyIndex": true,
        "templateFolder": "blank",
        "extTemplate": "",
        "showfolder": false,
        "reload": false,
        "sourceFolder": "src",
        "deployedVersion": "5.1.1",
        "x": 1050,
        "y": 100,
        "wires": [
            [],
            [
                "63f75a8ea70ce15f"
            ]
        ]
    },
    {
        "id": "63f75a8ea70ce15f",
        "type": "template",
        "z": "eca378ab71489651",
        "name": "",
        "field": "topic",
        "fieldType": "msg",
        "format": "handlebars",
        "syntax": "mustache",
        "template": "SELECT product, count(*) Qty FROM tag GROUP BY product;",
        "output": "str",
        "x": 300,
        "y": 260,
        "wires": [
            [
                "3e98159239f44a53"
            ]
        ]
    },
    {
        "id": "3e98159239f44a53",
        "type": "sqlite",
        "z": "eca378ab71489651",
        "mydb": "78507d7a12077e6d",
        "sqlquery": "msg.topic",
        "sql": "",
        "name": "tagdb",
        "x": 430,
        "y": 260,
        "wires": [
            [
                "ad95f815971ba501"
            ]
        ]
    },
    {
        "id": "ad95f815971ba501",
        "type": "function",
        "z": "eca378ab71489651",
        "name": "labels e values",
        "func": "var pValues = [];\nvar pLabels = [];\nvar data = msg.payload;\nvar l = data.length;\n\nfor (var i = 0; i < l; i++) {\n    pValues.push(data[i].Qty);\n    pLabels.push(data[i].product);\n}\n\nmsg.labels = pLabels;\nmsg.values = pValues;\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 620,
        "y": 260,
        "wires": [
            [
                "8868b4f1fce86c3b"
            ]
        ]
    },
    {
        "id": "8868b4f1fce86c3b",
        "type": "change",
        "z": "eca378ab71489651",
        "name": "topic tag",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "true",
                "tot": "bool"
            },
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "tag",
                "tot": "str"
            },
            {
                "t": "set",
                "p": "labels",
                "pt": "msg",
                "to": "labels",
                "tot": "msg"
            },
            {
                "t": "set",
                "p": "values",
                "pt": "msg",
                "to": "values",
                "tot": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 820,
        "y": 260,
        "wires": [
            [
                "bcf82d2f339ec188"
            ]
        ]
    },
    {
        "id": "bc90d7cdd72cdb9f",
        "type": "inject",
        "z": "eca378ab71489651",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 100,
        "y": 360,
        "wires": [
            [
                "63f75a8ea70ce15f"
            ]
        ]
    },
    {
        "id": "ec7a76f8d7091dc7",
        "type": "comment",
        "z": "eca378ab71489651",
        "name": "With manual inject it works",
        "info": "",
        "x": 210,
        "y": 400,
        "wires": []
    },
    {
        "id": "54457fc2c211c09d",
        "type": "comment",
        "z": "eca378ab71489651",
        "name": "with this connect it does dot update chart",
        "info": "",
        "x": 660,
        "y": 140,
        "wires": []
    },
    {
        "id": "78507d7a12077e6d",
        "type": "sqlitedb",
        "db": "/tmp/tagdb.db",
        "mode": "RWC"
    }
]

This is my html file:

<!doctype html>
<html lang="en">

<head>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css"
        integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>Citin Dashboard</title>
    <meta name="description" content="Node-RED uibuilder - Blank template">
    <link rel="icon" href="./images/node-blue.ico">

    <!-- Your own CSS -->
    <link type="text/css" rel="stylesheet" href="./index.css" media="all">
    <script src="https://code.jquery.com/jquery-3.6.0.js"
        integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>

<body>
    <nav class="navbar navbar-expand-lg navbar-dark sticky-top" style="background-color: #0d223f;">
        <div class="container-fluid">
            <a class="navbar-brand" href="/home">
                TAG
            </a>
        </div>
    </nav>
    <div class="container-fluid">
        <div class="row">
            <div class="col-md-6 col-sm-12 mycol">
                <div class="row m-2">
                    <div class="col-md-6 col-sm-12">
                        <h3>Device status</h3>
                        <button class="btn  mygreen mb-auto">OFF</button>
                    </div>
                    <div class="col-md-6 col-sm-12">
                        <h3>Active Tags</h3>
                        <h1 class="bignumber">0</h1>
                    </div>
                </div>
                <div class="row">
                    <div id="mycontainer">

                    </div>
                </div>
            </div>
            <div class="col-md-6 col-sm-12">
                <canvas id="myChart" width="400" height="400"></canvas>
            </div>
        </div>


    </div>


    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/js/bootstrap.bundle.min.js"
        integrity="sha384-A3rJD856KowSb7dwlZdYEkO39Gagi7vIsF0jrRAoQmDKKtQBHUuLZ9AsSv4jD4Xa" crossorigin="anonymous">
    </script>
    <!-- #region Supporting Scripts. These MUST be in the right order. Note no leading / -->
    <script src="../uibuilder/vendor/socket.io/socket.io.js">
        /* REQUIRED: Socket.IO is loaded only once for all instances. Without this, you don't get a websocket connection */
    </script>
    <script src="./uibuilderfe.min.js">
        /* REQUIRED: remove 'min.' to use dev version */
    </script>
    <script src="./index.js">
        /* OPTIONAL: Put your custom code here */
    </script>
    <!-- #endregion -->

</body>

</html>

Index.js File:

'use strict'

// run this function when the document is loaded
window.onload = function () {
    console.info("1");

    // Start up uibuilder - see the docs for the optional parameters
    uibuilder.start();
    console.info("2");


    const ctx = document.getElementById('myChart');
    const myChart = new Chart(ctx, {
        type: 'bar',
        data: {
            labels: [],
            datasets: [{
                label: 'Product Cumulative',
                backgroundColor: 'rgb(255, 99, 132)',
                borderColor: 'rgb(149, 214, 0)',
                data: [],
                borderWidth: 1
            }]
        },
        options: {
            scales: {
                y: {
                    beginAtZero: true
                }
            }
        }
    });

    // Listen for incoming messages from Node-RED
    uibuilder.onChange('msg', function (msg) {
        console.log(msg);


        if (msg.topic == 'tag') {
            console.info(msg);
            myChart.data.labels = msg.labels;
            myChart.data.datasets[0].data = msg.values;
            myChart.update();
        }

    })
}

and the css file:

.mycol{
    align-content: center;
    text-align: center;
}

.btn{
    width: 192px;
    font-size: x-large;

}

.bignumber{
    font-size: 4rem;
}

.thead-dark{
    background: gainsboro;
}
.myred{
    background: red;
    color: white;
}
.mygreen{
    background: green;
    color: white;
}
.card {
    padding: 1rem;
    border: 1px solid black;
    margin: 1rem;
    }

if you add a complete object Debug node after the "topic tag" Change node .. you will see that your data from sql is there but you have also left in the msg, uibuilder internal control properties, that tell uibuilder to ignore the msg as a normal msg.

image

It happened to me also before and @TotallyInformation explained this in some other thread .. which i cant find to link now. (its one of those things that you have to remember .. yea, like i remembered that flows can be triggered using the uib Ctrl msgs :wink: )

So to solve this a good place to make a new clean msg would be in that Function node

let newMsg = {};  // create newMsg

var pValues = [];
var pLabels = [];
var data = msg.payload;
var l = data.length;

for (var i = 0; i < l; i++) {
   pValues.push(data[i].Qty);
   pLabels.push(data[i].product);
}

newMsg.labels = pLabels;  // add to newMsg
newMsg.values = pValues;
return newMsg;

Many thanks. I already found the solution. that is not perfect but was working. Creating a new message before the SQL query. Your solution is cleaner and better.

1 Like