I'm trying to insert data from an Sqlite3 database into a web page hosted by a Beaglebone black. Using a JavaScript web worker form an on line example for a number count, the JS worker and HTML page work fine. If I modify the worker code to get the data from a database,and run that in a terminal on the host, that also works fine, the data base is accessed and the data printed out. However, the code will NOT operate as a worker. HTML code (wkr_tst.html)
<!DOCTYPE html>
<html>
<body>
<p>Count numbers: <output id="result"></output></p>
<p>Count numbers: <output id="result2"></output></p>
<button onclick="startWorker()">Start Worker</button>
<button onclick="stopWorker()">Stop Worker</button>
<script>
var w;
function startWorker() {
if (typeof(Worker) !== "undefined") {
if (typeof(w) == "undefined") {
w = new Worker("dbase1.js");
}
w.onmessage = function(event) {
document.getElementById("result").innerHTML = event.data;
document.getElementById("result2").innerHTML = event.data;
};
} else {
document.getElementById("result").innerHTML = "Sorry! No Web Worker support.";
}
}
function stopWorker() {
w.terminate();
w = undefined;
}
</script>
</body>
</html>
JavaScript worker:(dbase1.js)
const sqlite3 = require("sqlite3")
var i = 0;
const db = new sqlite3.Database("/home/debian/examples/C_BMS/test2.db",sqlite3.OPEN_READONLY );
function timedCount() {
i=i+1;
db.all("SELECT * FROM EpiData", [], (err, rows) => {
console.log(rows);
})
postMessage(rows);
//postMessage(i);
//postMessage(i+2);
//setTimeout("timedCount()",500);
}
timedCount();
db.close();
With 2 different browsers, using the inspect function, both show that the "require(Sqlite3) function is not defined.
I've tried re-installing both Node.js and the squlite3 extension, with the same result.
Web Workers in JS
running in the brower don't have access to require("sqlite3")
cuz it is a Nodejs
module.
I suggest you to separate client side (Web Worker) from server side (Nodejs)
.
Here is an example of what you can do:
1. Server side code (Nodejs)
npm install --save cors
or yarn add cors
const express = require('express');
const cors = require('cors');
const sqlite3 = require('sqlite3').verbose();
const app = express();
app.use(cors()); //this enables cors for everyone, first try this and check if your code works
/*
do this if you only want specific address to have access to the route
app.use(cors({
origin: 'http://192.168.0.52', //replace with the actual frontend URL
optionsSuccessStatus: 200
}));
*/
const port = 3000; //you can change this port to whatever port you want
const db = new sqlite3.Database('/home/debian/examples/C_BMS/test2.db', sqlite3.OPEN_READONLY);
//make an endpoint to fetch data
app.get('/data', (req, res) => {
db.all("SELECT * FROM EpiData", [], (err, rows) => {
if (err) {
res.status(500).json({ error: err.message });
return;
}
res.json(rows);
});
});
app.listen(port, () => {
console.log(`Listening on port ${port}`);
});
2. Web Worker (dbase1.js)
function timedCount() {
fetch('http://<your-server-ip>:3050/data') // changed this line from `fetch("/data")`
.then(response => response.json())
.then(data => {
postMessage(data); //send data back to the main thread
})
.catch(error => {
console.error(error);
postMessage('Error fetching data');
});
}
timedCount();
3. wkr_tst.html
<html>
<body>
<p>Count numbers: <output id="result"></output></p>
<p>Count numbers: <output id="result2"></output></p>
<button onclick="startWorker()">Start Worker</button>
<button onclick="stopWorker()">Stop Worker</button>
<script>
var w;
function startWorker() {
if (typeof(Worker) !== "undefined") {
if (typeof(w) == "undefined") {
w = new Worker("dbase1.js");
}
w.onmessage = function(event) {
document.getElementById("result").innerHTML = JSON.stringify(event.data, null, 2);
document.getElementById("result2").innerHTML = JSON.stringify(event.data, null, 2);
};
} else {
document.getElementById("result").innerHTML = "Sorry! No Web Worker support.";
}
}
function stopWorker() {
w.terminate();
w = undefined;
}
</script>
</body>
</html>
Note: Make sure that both your frontend
(HTML) and backend
(Nodejs) are running on BeagleBone Black
and they are served via a web server or nodejs server, and maybe you also have to enable cors
(in Nodejs code). Or you can also serve static HTML file with express too.
app.use(express.static('path to your html file'));
Hope this helps you.