highcharts / highcharts-react

The official Highcharts supported wrapper for React

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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

iamamar11 opened this issue · comments

commented

While working with Highcharts in a React application, I encountered a TypeError when attempting to update the chart type dynamically. The error occurs when updating the chart type and seems to be related to internal Highcharts methods. However, I'm uncertain about the exact cause of the issue. This Error only occur while testing the code using Jest and react testing library.

Steps to Reproduce:

  1. Initialize a Highcharts chart in a React component with an initial chart type (e.g., column).
  2. Attempt to dynamically update the chart type to another type (e.g., line).
  3. Observe the error in the console.

Expected Behavior:
I expected the chart to update its type smoothly without encountering any errors (Working on browser but throwing error while testing)

Actual Behavior:
Instead, a TypeError occurred during the chart type update process.

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

  at a.setTickPositions (node_modules/highcharts/highcharts.src.js:20183:25)
  at a.setTickInterval (node_modules/highcharts/highcharts.src.js:20087:17)
  at a.setScale (node_modules/highcharts/highcharts.src.js:20560:21)
  at forEach (node_modules/highcharts/highcharts.src.js:30727:21)
      at Array.forEach (<anonymous>)
  at a.redraw (node_modules/highcharts/highcharts.src.js:30725:17)
  at a.update (node_modules/highcharts/highcharts.src.js:32761:21)
  at node_modules/highcharts-react-official/dist/webpack:/src/HighchartsReact.js:68:7
  at commitHookEffectListMount (node_modules/react-dom/cjs/react-dom.development.js:20573:26)
  at commitLifeCycles (node_modules/react-dom/cjs/react-dom.development.js:20634:11)
  at commitLayoutEffects (node_modules/react-dom/cjs/react-dom.development.js:23426:7)
  at HTMLUnknownElement.callCallback (node_modules/react-dom/cjs/react-dom.development.js:3945:14)
  at HTMLUnknownElement.callTheUserObjectsOperation (node_modules/jsdom/lib/jsdom/living/generated/EventListener.js:26:30)
  at innerInvokeEventListeners (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:338:25)
  at invokeEventListeners (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:274:3)
  at HTMLUnknownElementImpl._dispatch (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:221:9)
  at HTMLUnknownElementImpl.dispatchEvent (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:94:17)
  at HTMLUnknownElement.dispatchEvent (node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:231:34)
  at Object.invokeGuardedCallbackDev (node_modules/react-dom/cjs/react-dom.development.js:3994:16)
  at invokeGuardedCallback (node_modules/react-dom/cjs/react-dom.development.js:4056:31)
  at commitRootImpl (node_modules/react-dom/cjs/react-dom.development.js:23151:9)
  at unstable_runWithPriority (node_modules/scheduler/cjs/scheduler.development.js:468:12)
  at runWithPriority$1 (node_modules/react-dom/cjs/react-dom.development.js:11276:10)
  at commitRoot (node_modules/react-dom/cjs/react-dom.development.js:22990:3)
  at performSyncWorkOnRoot (node_modules/react-dom/cjs/react-dom.development.js:22329:3)
  at node_modules/react-dom/cjs/react-dom.development.js:11327:26
  at unstable_runWithPriority (node_modules/scheduler/cjs/scheduler.development.js:468:12)
  at runWithPriority$1 (node_modules/react-dom/cjs/react-dom.development.js:11276:10)
  at flushSyncCallbackQueueImpl (node_modules/react-dom/cjs/react-dom.development.js:11322:9)
  at flushSyncCallbackQueue (node_modules/react-dom/cjs/react-dom.development.js:11309:3)
  at batchedUpdates$1 (node_modules/react-dom/cjs/react-dom.development.js:22387:7)
  at act (node_modules/react-dom/cjs/react-dom-test-utils.development.js:1042:14)
  at Object.eventWrapper (node_modules/@testing-library/react/dist/pure.js:65:28)
  at Object.wrapEvent (node_modules/@testing-library/user-event/dist/cjs/event/wrapEvent.js:8:28)
  at Object.dispatchEvent (node_modules/@testing-library/user-event/dist/cjs/event/dispatchEvent.js:47:22)
  at Object.dispatchUIEvent (node_modules/@testing-library/user-event/dist/cjs/event/dispatchEvent.js:24:26)
  at Mouse.up (node_modules/@testing-library/user-event/dist/cjs/system/pointer/mouse.js:91:30)
  at PointerHost.release (node_modules/@testing-library/user-event/dist/cjs/system/pointer/index.js:74:28)
  at pointerAction (node_modules/@testing-library/user-event/dist/cjs/pointer/index.js:62:47)
  at Object.pointer (node_modules/@testing-library/user-event/dist/cjs/pointer/index.js:35:9)
  at node_modules/@testing-library/react/dist/pure.js:59:16

Chart.tsx

import React, {forwardRef, useState} from 'react'
import Highcharts from 'highcharts'
import HighchartsReact from 'highcharts-react-official'

export const Chart = (props) => {
  const {options} = props
  const [chartData, setChartData] = useState(options)

  function onButtonClick(chartType) {
    const newOptions = {
      ...chartData,
      chart: {
        ...chartData.chart,
        type: chartType,
      },
    }
    newOptions.series?.forEach(series => {
      series.type = chartType
    })
    setChartData(newOptions)
  }

  return (
    <>
      <HighchartsReact highcharts={Highcharts} options={chartData} ref={ref} />
      <button onClick={() => onButtonClick('column')}>Update Chart</button>
    </>
  )
}

data.ts

export const options = {
  chart: {
    type: 'spline',
  },
  series: [
    {
      data: [50, 100],
      marker: {
        symbol: 'triangle-down',
      },
      name: 'DATA 1',
      type: 'spline',
    },
    {
      data: [50, 60],
      marker: {
        symbol: 'circle',
      },
      name: 'DATA 2',
      type: 'spline',
    },
    {
      data: [70, 90],
      marker: {
        symbol: 'triangle',
      },
      name: 'DATA 3',
      type: 'spline',
    },
  ],
  title: {
    text: "Record",
  },
  tooltip: {
    shared: true,
  },
  xAxis: {
    categories: ['Term 1', 'Term 2'],
  },
  yAxis: {
    labels: {
      format: '{value}%',
    },
    title: {
      text: 'Marks',
    },
  },
}

Chart.test.tsx

import React from 'react'
import {Chart} from '../Chart'
import {options} from '../data'
import {render, screen} from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import '@testing-library/jest-dom/extend-expect'

describe('Chart', () => {
  it('should render Chart', async () => {
    const user = userEvent.setup()
    render(<Chart options={options} />)

    expect(screen.getByText(/Highcharts.com/i)).toBeInTheDocument() // just to see it chart is rendered
    await user.click(screen.getByRole('button', {name: 'Update Chart'})) // This update causes the issue
  })
})

Environment:

"highcharts": "^10.1.0",
"highcharts-react-official": "^3.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"@testing-library/jest-dom": "^5.16.4",
"@testing-library/react": "^13.3.0",
"@testing-library/user-event": "^14.1.1",
"@types/jest": "^29.5.0",

Hi @iamamar11,

Thank you for contacting us!

This problem has been already reported on the main Highcharts repository: highcharts/highcharts#17300

Please check the thread above and use one of the suggested workarounds or update you Highcharts version.

Best regards!