react-chartjs-2 TypeError: o.default is not a constructor (render.com deployment issue on webpage with charts)

72 views Asked by At

I'm working on displaying some charts from my MongoDB database for a weightlifting tracking application. Whenever I try to access the page that includes my charts on the deployed render.com website I get the following errors:

Uncaught TypeError: o.default is not a constructor
    at n.value (index.js:290:28)
    at n.value (index.js:98:12)
    at _s (react-dom.production.min.js:261:217)
    at ws (react-dom.production.min.js:260:446)
    at bs (react-dom.production.min.js:259:431)
    at react-dom.production.min.js:283:96
    at kl (react-dom.production.min.js:281:398)
    at ol (react-dom.production.min.js:270:269)
    at k (scheduler.production.min.js:13:203)
    at MessagePort.P (scheduler.production.min.js:14:128)
wl-stats:1 
        
        
       Failed to load resource: the server responded with a status of 404 ()

Oddly enough, when starting the web page locally (npm start) the chart displays correctly and the page has no issues. I am wondering why my page would not display on render.com if it works in the local environment. I have checked dependencies multiple times over and everything seems fine to the best of my knowledge. Any ideas of how I could get past these errors? For reference I have two deployments, one that is running the server (which works even when connecting from local enviroment) and my static site which everything works except the chart page.

wl-stats.js:

import React, { useState, useEffect } from 'react';
import { Line } from 'react-chartjs-2';
import axios from 'axios';
import { useUser } from '../UserContext';

const LineChart = ({ exerciseData, selectedExercise }) => {
  const selectedExerciseData = exerciseData[selectedExercise] || [];
  // Sort the data by date
  selectedExerciseData.sort((a, b) => new Date(a.date) - new Date(b.date));

  // Check if there's no data, and avoid rendering the chart
  if (selectedExerciseData.length === 0) {
    return <div>No data available.</div>;
  }

  // Extract timestamps and durations from selectedExerciseData
  const timestamps = selectedExerciseData.map((entry) => entry.date);
  const durations = selectedExerciseData.map((entry) => entry.duration);

  const data = {
    labels: timestamps,
    datasets: [
      {
        label: selectedExercise,
        data: durations,
        borderColor: 'rgba(75, 192, 192, 1)',
        backgroundColor: 'rgba(75, 192, 192, 0.2)',
        borderWidth: 2,
        pointBackgroundColor: 'rgba(75, 192, 192, 1)',
        pointRadius: 5,
        pointHoverRadius: 7,
      },
    ],
  };

  const options = {
    maintainAspectRatio: false,
    scales: {
      x: {
        type: 'time',
        title: {
          display: true,
          text: 'Date',
        },
      },
      y: {
        beginAtZero: true,
        title: {
          display: true,
          text: 'Duration',
        },
      },
    },
    plugins: {
      legend: {
        labels: {
          fontSize: 25,
        },
      },
    },
  };

  return (
    <div>
      <Line data={data} height={400} width={600} options={options} />
    </div>
  );
};

const StatsWeightlifting = () => {
  const [selectedExercise, setSelectedExercise] = useState(''); // Set a default value here
  const [exerciseData, setExerciseData] = useState({});
  const [haveData, setHaveData] = useState(false); // New state for data availability

  const user = useUser();

  useEffect(() => {
    const fetchUserExerciseData = async () => {
      try {
        const response = await axios.get('https://dumbbell-data.onrender.com/exercises/');
        const userExercises = response.data.filter(
          (exercise) => exercise.email === user.currentUser
        );

        const reformattedData = {};

        userExercises.forEach((exercise) => {
          const date = exercise.date.substring(0, 10);
          if (!reformattedData[exercise.description]) {
            reformattedData[exercise.description] = [];
          }

          reformattedData[exercise.description].push({
            date,
            duration: exercise.duration,
          });
        });

        setExerciseData(reformattedData);
        setHaveData(true); // Set to true when data is available

        // Set the default selected exercise 
        if (Object.keys(reformattedData).length > 0) {
          setSelectedExercise(Object.keys(reformattedData)[0]);
        }
      } catch (error) {
        console.log(error);
        setHaveData(false); // Set to false on error
      }
    };

    fetchUserExerciseData();
  }, [user.currentUser]);

  return (
    <div>
      <h1>Weightlifting Stats</h1>
      <select
        value={selectedExercise}
        onChange={(e) => setSelectedExercise(e.target.value)}
      >
        {Object.keys(exerciseData).map((exercise) => (
          <option key={exercise} value={exercise}>
            {exercise}
          </option>
        ))}
      </select>
      {haveData ? ( // Conditionally render based on data availability
        <LineChart exerciseData={exerciseData} selectedExercise={selectedExercise} />
      ) : (
        <div>Loading...</div>
      )}
    </div>
  );
};



export default StatsWeightlifting;

I have tried a few things such as checking the dependencies and attempting to wait until the data had arrived to render the chart but nothing has worked. I can't understand why render.com won't display the page when the local environment will display even when connected to the deployed server.

0

There are 0 answers