How can I execute my code after data load is finished on my react project

Fathe Karim

I am creating a graph chart using chart js. My problem is the code is running before the data is loading that's why I am getting errors. I want after the data load the code will execute, I used loading state but it's not working also used optional chaining.

Data fetching code is

   useEffect(() => {
        setLoading(true)
        fetch('./fakeDta.json')
            .then(res => res.json())
            .then(data => setSchedules(data))
            .finally(() => setLoading(false))
    }, [])

The errors are

TypeError: Cannot convert undefined or null to object

TypeError: Cannot read properties of undefined (reading 'filter')

The main error is here:

 const chart2 = schedulesByDate(date)
 Object?.entries(chart2)?.map(
        ([key, value]) => {
            dateLabels.push(key);
            previousDateSchedules.push(value)

        }

Full code

import { Chart, registerables } from "chart.js";
import React, { useEffect, useRef, useState } from "react";
import { Bar } from "react-chartjs-2";
import './chart.css'
Chart.register(...registerables);


function BarChart() {
    const inputRef1 = useRef()
    const [date, setDate] = useState('')
    const [laoding, setLoading] = useState(false)

    // First chart date labels and value
    let dateLabels = []
    let previousDateSchedules = []

    // Data
    const [schedules, setSchedules] = useState()

    useEffect(() => {
        setLoading(true)
        fetch('./fakeDta.json')
            .then(res => res.json())
            .then(data => setSchedules(data))
            .finally(() => setLoading(false))
    }, [])

    // Bar chart option
    let options = {
        scales: {
            y: {
                max: 10,
                ticks: {
                    stepSize: 1
                }
            }
        }
    };


    // Chart 1 Function Start
    const schedulesByDate = (date) => {
        let dbItemDate = date;
        let otherDayArray = schedules?.filter(num => num.item_date < dbItemDate);
        let count = otherDayArray?.reduce(function (acc, num) {

            acc[num.item_date] = (acc[num.item_date] || 0) + 1;
            return acc;
        }, []);
        console.log(count);//this should print the frequency of each date in the others date array 
        return count


    }

    const chart2 = schedulesByDate(date)

    Object?.entries(chart2)?.map(
        ([key, value]) => {
            dateLabels.push(key);
            previousDateSchedules.push(value)

        }
    )
    // Chart 1 Function End


    //function to get Chart 2 result
    let getScheduleCounter = (date) => {
        let scheduleCounter = {
            '9_12': [],
            '12_3': [],
            '3_6': [],
            '6_9': []
        };

        schedules.forEach(sch => {
            if (sch.item_date === date) {
                updateScheduledCounter(sch, scheduleCounter);
            }
        });

        return scheduleCounter;
    }

    //function to get the count and update in scheduleCounter 
    let updateScheduledCounter = (sch, scheduleCounter) => {
        let time = sch.schedule_time.split(' ')[1];
        switch (!!time) {
            case (time <= '12:00:00'):
                scheduleCounter['9_12']++;
                break;

            case (time >= '12:00:00' && time <= '15:00:00'):
                scheduleCounter['12_3']++;
                break;

            case (time >= '15:00:00' && time <= '18:00:00'):
                scheduleCounter['3_6']++;
                break;

            case (time >= '18:00:00' && time <= '21:00:00'):
                scheduleCounter['6_9']++;
                break;
        }
    }

    let schedulesTimes = []
    let schedulesTimesValues = []

    let schedule = getScheduleCounter(date);
    console.log('schedules: ', schedule);


    Object.entries(schedule).map(
        ([key, value]) => {
            schedulesTimes.push(key);
            schedulesTimesValues.push(value)

        }
    )

    console.log(schedulesTimes, schedulesTimesValues);



    return (
        <>
            {
                laoding ? <h2>loading....</h2> : <div className="container">

                    <div className="bar">
                        <div classNam="chart-container" style={{ position: "relative", height: "550px", width: "40vw" }}>
                            <h2>Item Dates</h2>
                            <Bar
                                id="myChart"

                                data={{
                                    labels: dateLabels,
                                    datasets: [{
                                        label: 'Scheduled',
                                        data: previousDateSchedules,
                                        backgroundColor: [
                                            'rgba(255, 26, 104, 0.2)',
                                            'rgba(54, 162, 235, 0.2)',
                                            'rgba(255, 206, 86, 0.2)',
                                            'rgba(75, 192, 192, 0.2)',
                                            'rgba(153, 102, 255, 0.2)',
                                            'rgba(255, 159, 64, 0.2)',
                                            'rgba(0, 0, 0, 0.2)'
                                        ],
                                        borderColor: [
                                            'rgba(255, 26, 104, 1)',
                                            'rgba(54, 162, 235, 1)',
                                            'rgba(255, 206, 86, 1)',
                                            'rgba(75, 192, 192, 1)',
                                            'rgba(153, 102, 255, 1)',
                                            'rgba(255, 159, 64, 1)',
                                            'rgba(0, 0, 0, 1)'
                                        ],
                                        borderWidth: 1
                                    }]
                                }}

                                options={options}
                            />
                        </div>
                        <div className="chart-container" style={{ position: "relative", height: "550px", width: "40vw" }}>
                            <h2>{date} Schedules</h2>
                            <Bar
                                id="myChart"
                                data={{
                                    labels: ['9am to 12pm', '12pm to 3pm', '3pm to 6pm', '6pm to 9pm'],
                                    datasets: [{
                                        label: 'Scheduled',
                                        data: schedulesTimesValues,
                                        backgroundColor: [
                                            'rgba(255, 26, 104, 0.2)',
                                            'rgba(54, 162, 235, 0.2)',
                                            'rgba(255, 206, 86, 0.2)',
                                            'rgba(75, 192, 192, 0.2)',
                                            'rgba(153, 102, 255, 0.2)',
                                            'rgba(255, 159, 64, 0.2)',
                                            'rgba(0, 0, 0, 0.2)'
                                        ],
                                        borderColor: [
                                            'rgba(255, 26, 104, 1)',
                                            'rgba(54, 162, 235, 1)',
                                            'rgba(255, 206, 86, 1)',
                                            'rgba(75, 192, 192, 1)',
                                            'rgba(153, 102, 255, 1)',
                                            'rgba(255, 159, 64, 1)',
                                            'rgba(0, 0, 0, 1)'
                                        ],
                                        borderWidth: 1
                                    }]
                                }}

                                options={options}
                            />
                        </div>
                    </div>


                    <div>
                        <input type="date" ref={inputRef1} defaultValue='2021-05-18' />
                        <button onClick={() => setDate(inputRef1.current.value)}>Filter</button>
                    </div>
                </div>
            }
        </>
    );
}

export default BarChart;
adrian

A few things that might be causing the problem:

  1. Typo for loading in code, you have laoding but it should be loading. However this isn't likely a big issue as you still try to access schedule data higher up in your code before it has been set to the result of your fetch.
  2. For readability, update your ternary to wrap the results of: <div className="container"> ... in brackets
  3. The fetch function is async and returns a promise, meaning you'll have to wrap your fetch call in the useEffect in an async function:
  useEffect(()=>{
  const fetchData = async () => {
     fetch('./fakeDta.json')
           .then(res => res.json())
           .then(data => setSchedules(data))
           .finally(() => setLoading(false))
   };

   fetchData();
 },[])

  1. Under your use effect I would check that schedule actually has data, before preforming actions on it (as it'll cause those errors you're getting if schedule is empty) - something like:
if(!schedule){
  return <div>Loading</div>
}

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

How can I execute code after sending my response when I use cloudflare workers

How can I pass data loaded when my application finished launching thru my UITabBar to a UITableView?

How can I properly load a Python class in my project?

how i can execute what my code by condition with selenium?

How can I get my firebase listener to load data to my redux state in a React Native app so I can read the data within my ComponentDidMount function?

How i can Validate Purchase and get Purchase info(to create receipt in my app) in future after order finished

How can I update my XAML while a database operation is ongoing and then update it again after it's finished?

How can I run my code upon class load?

How can I both load my Simulink model to my Arduino and add also my own code with it?

How can I find in code path of my current project?

How can I add code from Github into my Codepen project?

In VS Code, how can I break my project into multiple files?

How can I use sass in my React / webpack project?

How I can update my react project in a running server

How can I load data in my select number two?

How can I load my data before the component is loaded?

How can I make my JavaScript (if it's correct) execute after my countdown?

How can I track down why my activity gets finished?

How to fix my code so that I can use the data from componentDidMount (React)

How can I send data (string) from my html to my server (node or express) and execute certain function with it?

How can I execute a shortcut in my path

React Native: How can I detect if my code is running in the Simulator?

How can I keep comments when minifying my React code?

How can I showcase the code snippets in my react app?

How can i simplify my current React code?

How can I load dynamic images in my TableView given my code format?

How can I recover my data after formatting ubuntu with ubuntu?

How can I target the specific .data in my html code

How can I change database data in my code to something else?