chartjs-adapter-date-fns icon indicating copy to clipboard operation
chartjs-adapter-date-fns copied to clipboard

Uncaught TypeError: Cannot read properties of undefined (reading '_adapters')

Open Shriniket33 opened this issue 2 years ago • 14 comments

chartjs-adapter-date-fns.bundle.js:6225 Uncaught TypeError: Cannot read properties of undefined (reading '_adapters') at chartjs-adapter-date-fns.bundle.js:6225:10 at chartjs-adapter-date-fns.bundle.js:4:76 at chartjs-adapter-date-fns.bundle.js:5:2 (anonymous) @ chartjs-adapter-date-fns.bundle.js:6225 (anonymous) @ chartjs-adapter-date-fns.bundle.js:4 (anonymous) @ chartjs-adapter-date-fns.bundle.js:5

Shriniket33 avatar Nov 22 '22 07:11 Shriniket33

did you import/require/load Chart.js before the adapter?

kurkle avatar Dec 10 '22 18:12 kurkle

I ran into this error using Vite. Adding "chartjs-adapter-date-fns" to ssr.noExternal makes it go away. I previously had to mark "chart.js" as noExternal due to https://github.com/chartjs/Chart.js/issues/9436 - perhaps there is a similar root cause?

woconnor avatar Dec 12 '22 06:12 woconnor

Adding "chartjs-adapter-date-fns" to ssr.noExternal makes it go away. I previously had to mark "chart.js" as noExternal due to https://github.com/chartjs/Chart.js/issues/9436 - perhaps there is a similar root cause?

When using sveltekit, I've had to do the same; added both to ssr.noExternal. Otherwise, an error would be thrown when all of the following was true:

  1. Page is being rendered server-side.
  2. sveltekit is not running in dev mode

thenbe avatar Dec 17 '22 09:12 thenbe

I'm getting this issue too when using VueJS.

I'm certain I've imported in the correct order, here is my component:

import { ref, toRef, watch } from 'vue';

import {
    Chart,
    TimeScale,
    ...
} from 'chart.js'

import 'chartjs-adapter-date-fns';
import { options } from './GraphConfig/TimelineGraph'

import {Bar, Line} from 'vue-chartjs'

Chart.register(
    ...
)

And here's the error:

[Vue warn]: Unhandled error during execution of async component loader
 |-> Uncaught (in promise) TypeError: Cannot read properties of undefined (reading '_adapters')

My implementation isn't using Server-side rendering, so it can't be solved using the same process as some of the other replies.

danhanly avatar Jan 09 '23 14:01 danhanly

I also attempted to include the adapter via a script tag in my HTML, loading after my Vue application to the same results. So this problem doesn't seem to be strictly related to the import process, but rather that this package imports correctly, but is unable to access the chart instance in order to override the _adapters

I may be incorrect here, but this seems to be that this package isn't "waiting" for an active ChartJS instance before actioning. My VueJS application runs as a deferred script, and I believe that this is causing issues here - this would also line up with users who are experiencing issues with SSR applications.

Is there a way to include the adapter in a different way? The way it currently does it, it just automatically overrides the _adapters, but if there's no ChartJS instance yet (because everything's being loaded as async), then it fails.

danhanly avatar Jan 09 '23 15:01 danhanly

I've managed to solve it by way of a fork - and the way I solved it was to ensure it's not dynamically loading onto the chart instance.

https://github.com/danhanly/chartjs-adapter-date-fns/blob/master/src/index.js

I export the adapter code as an object constant, which I then import and apply to my chart instance manually (at a time when I know the chart instance is correctly loaded).

// ChartJS import
import {
    Chart,
    _adapters,
    ...
} from 'chart.js'

// my forked version
import { dateFnsAdapter } from "chartjs-adapter-date-fns"

// Within my component's setup() method
_adapters._date.override(dateAdapter)

This may help those users who had an issue with it on SSR too, as we are now in full control over when the override occurs with no in-package guesswork. Of course, there's the extra override line you have to manage, so swings and roundabouts.

danhanly avatar Jan 09 '23 15:01 danhanly

I'm also seeing this, is there no official fix yet?

lobaak avatar Mar 14 '23 07:03 lobaak

Encountered the same issue

seikosantana avatar Mar 21 '23 09:03 seikosantana

Same issue with webpack

Debugging, it seems that the prebundled dist files do not play nice with being re-bundled by the app becaue exports is no longer defined at the point of injecting dependencies, so it falls back to looking for the dependencies on the global.

To work around this I've added the following to my code

const ChartJs = require('chart.js');
const Chart = require('chart.js/auto');
const dateFns = require('date-fns');

// these are required because webpacking is a bit broken for the date-fns adapter
global.Chart = ChartJs;
global.dateFns = dateFns;

require('chartjs-adapter-date-fns');

wheresrhys avatar May 18 '23 11:05 wheresrhys

Nothing here is working for me, so I tried the moment adapter and it works straight away :(

CrossTheDev avatar May 25 '23 07:05 CrossTheDev

Nothing here is working for me, so I tried the moment adapter and it works straight away :(

This was actually my solution after hours of getting nowhere.

mattgatee avatar Jun 29 '23 01:06 mattgatee

I saved the file and added from a local folder which fixed the issue.

AndrewElans avatar Jul 10 '23 12:07 AndrewElans

I saved the file and added from a local folder which fixed the issue.

In the end, I did the same. This library is really simple, but it is not an ideal solution in general :(

CrossTheDev avatar Jul 10 '23 12:07 CrossTheDev

I think I found the root cause. If you have 3 script files loading one after another, ie chart.js, than adapter.js, than app.js, the finished load order is often different. This can be checked by sorting by Waterfall > End Time in chrome developer.

To keep the order as written, Promise shall be used. I explained it here on Stackoverflow

AndrewElans avatar Jul 14 '23 20:07 AndrewElans