1

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,
Feyto
  • 255
  • 11

0 Answers0