chrysb
Posts: 4
Joined: Wed Dec 15, 2021 11:17 pm

[highcharts-more] Cannot read properties of undefined (reading 'forEach')

I've encountered this bug that's very hard to reproduce, but when it happens, it crashes our entire site.

I'm using `react-highcharts` and this seems to only happen with `highcharts-more` that I'm using for an `arearange` chart.

I've printed out the data any time the chart is set to re-render, and the has never been anything null, nor empty arrays. The chart is only rendered when there is data. I've also set `allowChartUpdate` to FALSE to try to prevent any sort of updates, but this still happens.

Any ideas?

Code: Select all

TypeError: Cannot read properties of undefined (reading 'forEach')
    at t.<anonymous> (/_next/static/chunks/701-395453a8625de03bf211.js:1)
    at /_next/static/chunks/ee7bdd82-74ff22f2dfbc6e8fb0dc.js:1
    at Array.forEach (<anonymous>)
    at y (/_next/static/chunks/ee7bdd82-74ff22f2dfbc6e8fb0dc.js:1)
    at t.drawChartBox (/_next/static/chunks/ee7bdd82-74ff22f2dfbc6e8fb0dc.js:1)
    at t.a (/_next/static/chunks/701-395453a8625de03bf211.js:1)
    at t.<computed> [as drawChartBox] (/_next/static/chunks/ee7bdd82-74ff22f2dfbc6e8fb0dc.js:1)
    at t.redraw (/_next/static/chunks/ee7bdd82-74ff22f2dfbc6e8fb0dc.js:1)
    at t.update (/_next/static/chunks/ee7bdd82-74ff22f2dfbc6e8fb0dc.js:1)
    at /_next/static/chunks/496-129302bc687e97539f11.js:1
    at hu (framework-f34b8eb91682c54ca2f7.js:1)
    at Li (framework-f34b8eb91682c54ca2f7.js:1)
    at t.unstable_runWithPriority (framework-f34b8eb91682c54ca2f7.js:1)
    at Wl (framework-f34b8eb91682c54ca2f7.js:1)
    at Ti (framework-f34b8eb91682c54ca2f7.js:1)
    at vi (framework-f34b8eb91682c54ca2f7.js:1)
    at framework-f34b8eb91682c54ca2f7.js:1
    at t.unstable_runWithPriority (framework-f34b8eb91682c54ca2f7.js:1)
    at Wl (framework-f34b8eb91682c54ca2f7.js:1)
    at Ql (framework-f34b8eb91682c54ca2f7.js:1)
    at Hl (framework-f34b8eb91682c54ca2f7.js:1)
    at fi (framework-f34b8eb91682c54ca2f7.js:1)
    at No (framework-f34b8eb91682c54ca2f7.js:1)
    at t.updateResult (/_next/static/chunks/496-129302bc687e97539f11.js:1)
    at t.updateCurrentData (/_next/static/chunks/496-129302bc687e97539f11.js:1)
    at fr (_app-9886eec8df0568d9636c.js:1)
    at hr (_app-9886eec8df0568d9636c.js:1)
    at t.e.next (_app-9886eec8df0568d9636c.js:1)
    at Object.next (_app-9886eec8df0568d9636c.js:1)
    at fr (_app-9886eec8df0568d9636c.js:1)
    at hr (_app-9886eec8df0568d9636c.js:1)
    at t.e.next (_app-9886eec8df0568d9636c.js:1)
    at _app-9886eec8df0568d9636c.js:1
    at Array.forEach (<anonymous>)
    at _o (_app-9886eec8df0568d9636c.js:1)
    at Object.next (_app-9886eec8df0568d9636c.js:1)
    at Object.handler (_app-9886eec8df0568d9636c.js:1)
    at t.processReceivedData (_app-9886eec8df0568d9636c.js:1)
    at WebSocket.client.onmessage (_app-9886eec8df0568d9636c.js:1)
Our code is pretty abstracted so it will be hard to show you the whole flow, but here's the file in question:

Code: Select all

const generateChartData = (data: CollectionAnalyticsSalesTrendQuery) => {
  let series = [
    {
      type: 'column',
      borderWidth: 0,
      color: theme.colors.grey[400],
      name: 'Volume',
      yAxis: 0,
      data: [],
      tooltip: {
        valuePrefix: 'Ξ',
      },
      zoneAxis: 'x',
      zones: [
        {
          value: new Date(utcDate()).getTime(),
        },
        {
          dashStyle: 'dot',
        },
      ],
    },
    {
      type: 'line',
      borderWidth: 0,
      color: theme.colors.brand.primary,
      name: 'Avg. Price',
      yAxis: 1,
      data: [],
      zoneAxis: 'x',
      marker: {
        enabled: false,
      },
      tooltip: {
        valuePrefix: 'Ξ',
      },
      dashStyle: 'none',
      zIndex: 1,
      zones: [
        {
          value: new Date(utcDate()).getTime(),
        },
        {
          dashStyle: 'dot',
        },
      ],
    },
    {
      type: 'arearange',
      borderWidth: 0,
      color: theme.colors.brand[500],
      name: 'Range',
      yAxis: 1,
      opacity: 0.2,
      data: [],
      zoneAxis: 'x',
      marker: {
        enabled: false,
      },
      tooltip: {
        valuePrefix: 'Ξ',
      },
      zones: [
        {
          value: new Date(utcDate()).getTime(),
        },
        {
          dashStyle: 'dot',
        },
      ],
    },
    {
      type: 'line',
      borderWidth: 0,
      color: theme.colors.green[500],
      name: 'Median Price',
      yAxis: 1,
      data: [],
      zoneAxis: 'x',
      marker: {
        enabled: false,
      },
      tooltip: {
        valuePrefix: 'Ξ',
      },
      dashStyle: 'shortdot',
      visible: false,
      zIndex: 1,
      zones: [
        {
          value: new Date(utcDate()).getTime(),
        },
        {
          dashStyle: 'dot',
        },
      ],
    },
  ]
  data.salesTrends.map((s) => {
    const date = moment(s.date).utc().valueOf()
    series[0].data.push([date, weiToEther(s.total_volume)])
    series[1].data.push([date, weiToEther(s.average_price)])
    series[2].data.push([
      date,
      weiToEther(s.sales_floor),
      weiToEther(s.max_price),
    ])
    series[3].data.push([date, weiToEther(s.median_price)])
  })

  return series
}

const CollectionAnalyticsVolumeChart = ({ collection, period }: Props) => {
  const [options, setOptions] = useState(null)
  const startDate = useMemo(
    () => moment.utc().subtract(period, 'days').toDate(),
    [period]
  )

  const { data, error, loading } = useCollectionAnalyticsSalesTrendQuery({
    variables: {
      address: collection.address,
      startDate,
    },
  })

  useEffect(() => {
    if (!data) return
    const series = generateChartData(data)

    const options = {
      ...defaultChartOptions,
      chart: {
        ...defaultChartOptions.chart,
        zoomType: 'x',
        height: 340,
      },
      plotOptions: {
        ...defaultChartOptions.plotOptions,
      },
      credits: {
        enabled: false,
      },
      xAxis: {
        type: 'datetime',
        labels: {
          formatter: function () {
            return Highcharts.dateFormat('%b %e', this.value)
          },
        },
        title: {
          text: undefined,
        },
      },
      yAxis: [
        {
          crosshair: {
            color: '#ffffff40',
          },
          title: { text: 'Volume', enabled: false },
          labels: {
            format: '{value:.1f}',
          },
        },
        {
          type: 'logarithmic',
          crosshair: {
            color: '#ffffff40',
          },
          title: { text: 'Price', enabled: false },
          labels: {
            format: '{value:.1f}',
          },
          opposite: true,
        },
        {
          type: 'logarithmic',
          crosshair: {
            color: '#ffffff40',
          },
          title: { enabled: false },
          labels: {
            format: '{value:.1f}',
          },
          opposite: true,
        },
        {
          type: 'logarithmic',
          crosshair: {
            color: '#ffffff40',
          },
          title: { enabled: false },
          labels: {
            format: '{value:.1f}',
          },
          opposite: true,
        },
      ],
      tooltip: {
        ...defaultChartOptions.tooltip,
        shared: true,
        borderColor: theme.colors.brand.primary,
        formatter: function () {
          return tooltipFormatter(this)
        },
      },
      series: series,
    }
    setOptions(options)
  }, [data])

  return (
    <ChartWrapper
      title='Volume &amp; Price'
      period={period}
      isLoading={loading}
      options={options}
      hasData={data?.salesTrends.length > 0}
      height={300}
      error={error}
      useMore={true}
      allowChartUpdate={false} // Prevent stupid bug?
    />
  )
}
michal.f
Posts: 1114
Joined: Thu Aug 12, 2021 12:04 pm

Re: [highcharts-more] Cannot read properties of undefined (reading 'forEach')

Hello,

Welcome to our forum and thanks for contacting us with your question!

It is difficult to say what the problem may be. If you can't reproduce the bug in an online editor like StackBlitz or CodeSandbox, or even in a new project, the problem may not be directly related to Highcharts.

Best regards!
Michał Filipiec
Highcharts Developer
https://blacklabel.pl/highcharts/
chrysb
Posts: 4
Joined: Wed Dec 15, 2021 11:17 pm

Re: [highcharts-more] Cannot read properties of undefined (reading 'forEach')

Hi there, thank you.

I was able to resolve the issue by ejecting the src and editing it to fix the bug. When adding highcharts-more, it adds an afterDrawChartBox event where sometimes pane is null, and causes a crash.

Code: Select all

      addEvent(Chart, 'afterDrawChartBox', function () {
        if (this.pane) {
          this.pane.forEach(function (pane) {
            pane.render()
          })
        }
      })

Where can I submit a PR to fix this issue in highcharts-more?
michal.f
Posts: 1114
Joined: Thu Aug 12, 2021 12:04 pm

Re: [highcharts-more] Cannot read properties of undefined (reading 'forEach')

Hi,

If you are sure that this is a problem strictly with Highcharts and not with the React wrapper, you can report it in the official repository on GitHub: https://github.com/highcharts/highcharts/issues

But if you are not sure, it is best to report it here: https://github.com/highcharts/highcharts-react/issues

Feel free to ask any further questions!
Best regards!
Michał Filipiec
Highcharts Developer
https://blacklabel.pl/highcharts/

Return to “Highcharts Usage”