I'm relatively new to react and I'm facing some problems with charts, I do have an array of integers and I'm trying to pass this array of integers in the chart component that I have created as prop but I get 2 errors.
1:
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'x')
at t.value (apexcharts.common.js:6:113947)
at t.value (apexcharts.common.js:6:113596)
at t.value (apexcharts.common.js:6:120591)
at t.value (apexcharts.common.js:6:123454)
at t.value (apexcharts.common.js:15:37106)
at t.eval [as create] (apexcharts.common.js:6:4473)
at eval (apexcharts.common.js:15:36106)
at new Promise (<anonymous>)
at t.value (apexcharts.common.js:15:21675)
at r.value (react-apexcharts.min.js:1:2927)
at safelyCallComponentDidMount (react-dom.development.js:22877:14)
at reappearLayoutEffectsOnFiber (react-dom.development.js:23531:11)
at reappearLayoutEffects_complete (react-dom.development.js:24833:7)
at reappearLayoutEffects_begin (react-dom.development.js:24821:7)
at commitLayoutEffects_begin (react-dom.development.js:24644:11)
at commitLayoutEffects (react-dom.development.js:24607:3)
at commitRootImpl (react-dom.development.js:26818:5)
at commitRoot (react-dom.development.js:26677:5)
at finishConcurrentRender (react-dom.development.js:25976:9)
at performConcurrentWorkOnRoot (react-dom.development.js:25804:7)
at workLoop (scheduler.development.js:266:34)
at flushWork (scheduler.development.js:239:14)
at MessagePort.performWorkUntilDeadline (scheduler.development.js:533:21)
2:
Unhandled Runtime Error TypeError: Cannot read properties of undefined (reading 'toString')
at t.value (apexcharts.common.js:6:390713)
at t.value (apexcharts.common.js:6:387088)
at t.value (apexcharts.common.js:15:36720)
at t.eval [as create] (apexcharts.common.js:6:4473)
at eval (apexcharts.common.js:15:36106)
at new Promise (<anonymous>)
at t.value (apexcharts.common.js:15:21675)
at r.value (react-apexcharts.min.js:1:2927)
at invokeLayoutEffectMountInDEV (react-dom.development.js:25128:22)
at invokeEffectsInDev (react-dom.development.js:27346:11)
at commitDoubleInvokeEffectsInDEV (react-dom.development.js:27322:5)
at flushPassiveEffectsImpl (react-dom.development.js:27051:5)
at flushPassiveEffects (react-dom.development.js:26979:14)
at eval (react-dom.development.js:26764:9)
at workLoop (scheduler.development.js:266:34)
at flushWork (scheduler.development.js:239:14)
at MessagePort.performWorkUntilDeadline (scheduler.development.js:533:21)
Here's where I make the Axios call and I call my component. I want to pass the Array TotalSalesArray to the component.
import Head from 'next/head';
import { Box, Container, Unstable_Grid2 as Grid } from '@mui/material';
import { Layout as DashboardLayout } from 'src/layouts/dashboard/admin/layout';
import axios from 'axios';
import { useEffect, useState } from 'react';
import { TotalSalesChart } from '../../sections/overview/Admin/TotalSalesChart';
const Page = () => {
const [currentMonth, setCurrentMonth] = useState([]);
const [data, setData] = useState([]);
const [totalSalesArray, setTotalSalesArray] = useState([]);
useEffect(() => {
axios.get('http://localhost:8001/admin/getSalesPerMonth', { withCredentials: true })
.then((response) => {
setCurrentMonth(response.data['currentMonth']);
setData(response.data['pastMonths']);
}).catch((error) => {
console.log(error);
});
},[]);
const totalSales = currentMonth[0]?.totalSales;
useEffect(() => {
const salesArray = Object.values(data).map(month => month.totalSales);
setTotalSalesArray([...salesArray.reverse(), totalSales]);
}, [data]);
return (
<>
<Head>
<title>
Overview
</title>
</Head>
<Box
component="main"
sx={{
flexGrow: 1,
py: 8
}}
>
<Container maxWidth="xl">
<Grid
container
spacing={3}
>
<Grid
xs={12}
lg={8}
>
<TotalSalesChart
chartSeries={[
{
name: 'This year',
data: totalSalesArray
}
]}
/>
</Grid>
</Grid>
</Container>
</Box>
</>
);
};
Page.getLayout = (page) => (
<DashboardLayout>
{page}
</DashboardLayout>
);
export default Page;
Here is the component code itself
import DotsHorizontalIcon from '@untitled-ui/icons-react/build/esm/DotsHorizontal';
import { Box, Card, CardContent, CardHeader, IconButton, SvgIcon } from '@mui/material';
import { useTheme } from '@mui/material/styles';
import { Chart } from '../../../components/chart';
import { Scrollbar } from '../../../components/scrollbar';
const useChartOptions = () => {
const theme = useTheme();
return {
chart: {
background: 'transparent',
stacked: false,
toolbar: {
show: false
},
zoom: {
enabled: false
}
},
colors: [theme.palette.primary.main],
dataLabels: {
enabled: false
},
fill: {
gradient: {
opacityFrom: 0.4,
opacityTo: 0.1,
stops: [0, 100]
},
type: 'gradient'
},
grid: {
borderColor: theme.palette.divider,
strokeDashArray: 2,
xaxis: {
lines: {
show: false
}
},
yaxis: {
lines: {
show: true
}
}
},
markers: {
size: 6,
strokeColors: theme.palette.background.default,
strokeWidth: 3
},
stroke: {
curve: 'smooth'
},
theme: {
mode: theme.palette.mode
},
xaxis: {
axisBorder: {
show: false
},
axisTicks: {
show: false
},
categories: [
'Jan',
'Feb',
'Mar',
'Apr',
'May',
'Jun',
'Jul',
'Aug',
'Sep',
'Oct',
'Nov',
'Dec'
],
labels: {
offsetY: 5,
style: {
colors: theme.palette.text.secondary
}
}
},
yaxis: {
labels: {
formatter: (value) => (value > 0 ? `${value}` : `${value}`),
offsetX: -10,
style: {
colors: theme.palette.text.secondary
}
}
}
};
};
export const TotalSalesChart = (props) => {
const { chartSeries } = props;
const chartOptions = useChartOptions();
return (
<Box
sx={{
backgroundColor: (theme) => theme.palette.mode === 'dark'
? 'neutral.800'
: 'neutral.100',
p: 3
}}
>
<Card>
<CardHeader
action={(
<IconButton>
<SvgIcon>
<DotsHorizontalIcon/>
</SvgIcon>
</IconButton>
)}
title="Sales chart"
/>
<CardContent>
<Scrollbar>
<Box
sx={{
height: 375,
minWidth: 500,
position: 'relative'
}}
>
<Chart
height={350}
options={chartOptions}
series={chartSeries}
type="area"
/>
</Box>
</Scrollbar>
</CardContent>
</Card>
</Box>
);
};
Here is a sample of totalSalesArray
:
[6020, 6890, 600, 600, 60, 60, 60, 750, 750, 7550, 232, 1500]
Issue: Unhandled Runtime Error TypeError: Cannot read properties of undefined (reading 'toString')
I encountered a runtime error in my React application with ApexCharts, manifesting as follows:
Unhandled Runtime Error TypeError: Cannot read properties of undefined (reading 'toString')
at t.value (apexcharts.common.js:6:390713)
at t.value (apexcharts.common.js:6:387088)
at t.value (apexcharts.common.js:15:36720)
at t.eval [as create] (apexcharts.common.js:6:4473)
at eval (apexcharts.common.js:15:36106)
at new Promise (<anonymous>)
at t.value (apexcharts.common.js:15:21675)
at r.value (react-apexcharts.min.js:1:2927)
at invokeLayoutEffectMountInDEV (react-dom.development.js:25128:22)
at invokeEffectsInDev (react-dom.development.js:27346:11)
at commitDoubleInvokeEffectsInDEV (react-dom.development.js:27322:5)
at flushPassiveEffectsImpl (react-dom.development.js:27051:5)
at flushPassiveEffects (react-dom.development.js:26979:14)
at eval (react-dom.development.js:26764:9)
at workLoop (scheduler.development.js:266:34)
at flushWork (scheduler.development.js:239:14)
at MessagePort.performWorkUntilDeadline (scheduler.development.js:533:21)
After encountering this error frequently without an apparent cause, I discovered that it was a bug in the ApexCharts library in React. The problem was resolved by upgrading to a version released in 2020. or just by putting width and height to the chart.
Solution:
Identify the bug in ApexCharts: GitHub Issue #1898
Upgrade ApexCharts in your React project or add a width to the chart. This resolved the issue for me.
Acknowledgments:
I want to express my gratitude to @CaseyC, who helped address the initial error. and to all people who took a portion of their time to reply. Additionally, the following code snippet proved helpful in preventing the issue:
if (!totalSalesArray.length || totalSalesArray == 0 || !totalSalesArray) {
return null;
}
This piece of code checks if the totalSalesArray
is null or undefined before attempting further operations.
I will change the title of the question to be more accurate for those who are facing the same problem (bug) in general.
I hope this information helps others facing a similar problem!