I tried to add curves to visualise data from a python program connected to the app.js program via a websocket. The data is well retrieved through the websocket as it is continuously displayed in the boxes of panel 1.
The graph displays well in the panel when I set fixed values but when I want to insert data["fs"]["s1"]["twist"]
from websocket data, I get the following error: App.js:51 Uncaught TypeError: Cannot read property 'fs' of nul at WebSocket.<anonymous> (App.js:51)
What i have tried :
I have tried to put [data] in the useeffect function but this made the display buggy (the data was displayed with a high frequency) and the connection to the websocket server was breaking several times.
I also added a try,catch in the app.js file to see if data is null. This block consistently returns the same error for the fs property.
I added these line in socket.addEventListener and it worked : da=[{x:JSON.parse(event.data)["fs"]["s1"]["twist"],y:1},{x:JSON.parse(event.data)["fs"]["s2"]["twist"],y:2},{x:5.5,y:3},{x:5,y:4},{x:5,y:5}]; chart(da)
But when i added line console.log(data)
, it printed null
in the console.
Question :
How do I get the data and insert it correctly into my chart without getting errors?
Here are the code :
Python :
import asyncio
import random
import datetime
import websockets
import json
sv={"fs":{
"s5":{"entry":2,"cfwd":3,"camber":2,"draft":3,"caft":5,"exit":5,"twist":15,"sag_lat":10,"sag_long":10},
"s4":{"entry":2,"cfwd":3,"camber":2,"draft":3,"caft":5,"exit":5,"twist":15,"sag_lat":10,"sag_long":10},
"s3":{"entry":2,"cfwd":3,"camber":2,"draft":3,"caft":5,"exit":5,"twist":15,"sag_lat":10,"sag_long":10},
"s2":{"entry":2,"cfwd":3,"camber":2,"draft":3,"caft":5,"exit":5,"twist":15,"sag_lat":10,"sag_long":10},
"s1":{"entry":2,"cfwd":3,"camber":2,"draft":3,"caft":5,"exit":5,"twist":15,"sag_lat":10,"sag_long":10},
},
"ms":{
"s5":{"entry":2,"cfwd":3,"camber":2,"draft":3,"caft":5,"exit":5,"twist":15,"sag_lat":10,"sag_long":10},
"s4":{"entry":2,"cfwd":3,"camber":2,"draft":3,"caft":5,"exit":5,"twist":15,"sag_lat":10,"sag_long":10},
"s3":{"entry":2,"cfwd":3,"camber":2,"draft":3,"caft":5,"exit":5,"twist":15,"sag_lat":10,"sag_long":10},
"s2":{"entry":2,"cfwd":3,"camber":2,"draft":3,"caft":5,"exit":5,"twist":15,"sag_lat":10,"sag_long":10},
"s1":{"entry":2,"cfwd":3,"camber":2,"draft":3,"caft":5,"exit":5,"twist":15,"sag_lat":10,"sag_long":10},
}}
async def handler(websocket, path):
while True:
#log_decoder()
for key1 in sv:
for key2 in sv[key1]:
sv[key1][key2]["entry"] = random.randint(1, 10)
sv[key1][key2]["cfwd"] = random.randint(1, 10)
sv[key1][key2]["camber"] = random.randint(1, 10)
sv[key1][key2]["draft"] = random.randint(1, 10)
sv[key1][key2]["caft"] = random.randint(1, 10)
sv[key1][key2]["exit"] = random.randint(1, 10)
sv[key1][key2]["twist"] = random.randint(1, 10)
sv[key1][key2]["sag_lat"] = random.randint(1, 10)
sv[key1][key2]["sag_long"] = random.randint(1, 10)
#data = [random.randint(0, 20) for _ in range(10)]
await websocket.send(json.dumps(sv))
await asyncio.sleep(1)
start_server = websockets.serve(handler, "localhost", 8000)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
App.js :
import React, { useState, useEffect, useRef, useSyncExternalStore } from 'react';
import Modal from './Modal/Modal'
import {Chart as ChartJS,LinearScale,PointElement,LineElement,Tooltip,Legend} from 'chart.js';
import {Scatter } from 'react-chartjs-2';
ChartJS.register(
LinearScale,
PointElement,
LineElement,
Tooltip,
Legend);
//JSON.parse(event.data)
//<Doughnut ref={chartReference} data={data} />
export default function App() {
let da;
const [data, setData] = useState(null);
const [chartData,setChartData]=useState({
datasets: [
{
label: 'A dataset',
showLine:true,
maintainAspectRatio:false,
fill:false,
data: [{x:3,y:1},{x:10,y:2},{x:5.5,y:3},{x:50,y:4},{x:5,y:5}],
backgroundColor: 'rgba(255, 99, 132, 1)',
borderColor: '#df9305'
}]
});
const [show,setShow] = useState(false);
const chart=(d) =>{
setChartData({
datasets: [
{
label: 'A dataset',
showLine:true,
maintainAspectRatio:false,
fill:false,
data: d,
backgroundColor: 'rgba(255, 99, 132, 1)',
borderColor: '#df9305'
}]
});
};
useEffect(() => {
const socket = new WebSocket('ws://localhost:8000');
socket.addEventListener('message', (event) => {
setData(JSON.parse(event.data));
});
try {
let twist = data["fs"]["s1"]["twist"];
// use the twist variable to update
da=[{x:data["fs"]["s1"]["twist"],y:1},{x:2,y:2},{x:5.5,y:3},{x:5,y:4},{x:5,y:5}];
chart(da)
} catch (err) {
// handle the error or show a default
console.log(err)
}
}, []);
return (
<div>
<div className="home">
<div className="template-1" id="temp1">
<div className="panel-1">
<div className="panel-header">
<h1>Foresail</h1>
<i className='bx bx-cog modal-trigger-panel'></i>
</div>
<div className="panel-body">
<div className="sec-5 modal-trigger-data" id="fs-sec-5" onClick={()=>setShow(true)}>
{data ? <span class="h1" id="h1-fs-s5">{data["fs"]["s5"]["twist"]}</span> : <span class="h1" id="h1-fs-s5">--</span>}
<h2>TWIST</h2>
<h3>s5</h3>
</div>
<div className="sec-4 modal-trigger-data" id="fs-sec-4" onClick={()=>setShow(true)}>
{data ? <span class="h1" id="h1-fs-s4">{data["fs"]["s4"]["twist"]}</span> : <span class="h1" id="h1-fs-s4">--</span>}
<h2>TWIST</h2>
<h3>s4</h3>
</div>
<div className="sec-3 modal-trigger-data" id="fs-sec-3" onClick={()=>setShow(true)}>
{data ? <span class="h1" id="h1-fs-s3">{data["fs"]["s3"]["twist"]}</span> : <span class="h1" id="h1-fs-s3">--</span>}
<h2>TWIST</h2>
<h3>s3</h3>
</div>
<div className="sec-2 modal-trigger-data" id="fs-sec-2" onClick={()=>setShow(true)}>
{data ? <span class="h1" id="h1-fs-s2">{data["fs"]["s2"]["twist"]}</span> : <span class="h1" id="h1-fs-s2">--</span>}
<h2>TWIST</h2>
<h3>s2</h3>
</div>
<div className="sec-1 modal-trigger-data" id="fs-sec-1" onClick={()=>setShow(true)}>
{data ? <span class="h1" id="h1-fs-s1">{data["fs"]["s1"]["twist"]}</span> : <span class="h1" id="h1-fs-s1">--</span>}
<h2>TWIST</h2>
<h3>s1</h3>
</div>
</div>
</div>
<div class="panel-3">
<div class="panel-header">
<h1>Courbes</h1>
<i class='bx bx-cog modal-trigger-panel'></i>
</div>
<div class="panel-body">
<Scatter options={{showLines:true,legend:{display:false}}} data={chartData} />
</div>
</div>
</div>
<Modal onClose={() => setShow(false)} show={show} />
</div>
</div>
);
}
Regards,