chartjs / chartjs-plugin-datalabels

Chart.js plugin to display labels on data elements
https://chartjs-plugin-datalabels.netlify.app
MIT License
863 stars 460 forks source link

Error: Cannot set properties of undefined (setting '_listened') #309

Open salmanorak opened 2 years ago

salmanorak commented 2 years ago

Definition

I have an application created with next.js which I am making client-side routing. I am using chartjs with datalabels on one page and I am getting a Cannot set properties of undefined (setting '_listened') error while making the page transition. It is not always happening. I couldn't find the exact case and I can not reproduce it with certain steps. But When I tried to make lots of concurrent page transition click sometimes it happens. So it is an unpredictable error that I am facing while demoing the application.

Can You please look into the details and provide some solution? Thanks

Implementation Details:

I have one dashboard page which has one doughnut chart. Also, I have different charts on some detailed reports. On the dashboard, I don't want to see the data labels but on reports, I want to have them. The plugin is

I am registering Datalabel Plugin globally like below:

import { ArcElement, Chart, Legend } from 'chart.js';
import ChartDataLabels from 'chartjs-plugin-datalabels';

Chart.register(ArcElement, Legend, ChartDataLabels);

I am disabling the datalabels plugin when it is not desired according to user selection with the below option settings. And Datalabels is disabled on the page, I am getting this error.

image

extra detail

Whole stack trace of error message on console image

I have followed up error line it it is showing the line in redbox

image

versions

"chart.js": "^3.6.1",
"chartjs-plugin-datalabels": "^2.0.0",
fstrazzante commented 2 years ago

I got the same error. In my case I registered the plugin globally but needed only in one chart. I switch from registered globally to the exact chart and now I don't have the error anymore.

The conf of the chart that is using this plugin is something like this (I'm using plain JS) : { type: 'pie', data: {.....}, plugins: [ChartDataLabels], options: {...} }

chiexclusive commented 1 year ago

Have you resolved this, and how did you go about this. I have been on this issue for weeks

salmanorak commented 1 year ago

Actually I am not sure how it is related with the solution I am going to share it but it has resolved my issue.

In my case there was a link on the page which what navigating same page with # suffix. When I clicked on this link, the error was occuring. I have added a control to that link if it is on same page it became passive/disabled so it is not going to redirect to same page. So error is not throwing.

chiexclusive commented 1 year ago

Thanks, I think I just resolved mine now, although am still testing. I removed all the plugin registration from the top of the file and added them at the top of the component, because in my case I have various chart file that needed specific plugins and I was registering all the plugins globally

On Sat, Jul 16, 2022, 4:55 PM Salman ORAK @.*** wrote:

Actually I am not sure how it is related with the solution I am going to share it but it has resolved my issue.

In my case there was a link on the page which what navigating same page with # suffix. When I clicked on this link, the error was occuring. I have added a control to that link if it is on same page it became passive/disabled so it is not going to redirect to same page. So error is not throwing.

— Reply to this email directly, view it on GitHub https://github.com/chartjs/chartjs-plugin-datalabels/issues/309#issuecomment-1186225189, or unsubscribe https://github.com/notifications/unsubscribe-auth/AILHRVL6F36RXAN2IWSDUDTVULLQZANCNFSM5R3QHWDA . You are receiving this because you commented.Message ID: @.***>

simonbrunel commented 1 year ago

The only reason I'm thinking that _listened would be undefined is if the beforeInit() hook hasn't been called before beforeUpdate(). @kurkle do you think of any case where this can happen?

@salmanorak your setup is complex (and unpredictable) and we don't have time (or knowledge) to figure out ourselves how to recreate a next.js project that actually reproduces this error. So please share a repo that we can use to debug your issue, with instructions how to build, run and generate this issue.

kurkle commented 1 year ago

The only reason I'm thinking that _listened would be undefined is if the beforeInit() hook hasn't been called before beforeUpdate(). @kurkle do you think of any case where this can happen?

Yes, there is a long review thread also discussing about disabled plugins not getting beforeInit hook called (it is only called from chart constructor). https://github.com/chartjs/Chart.js/pull/8103

But as the plugin is disabled with { display: false }, it should be called.

Could have something to do with SSR?

simonbrunel commented 1 year ago

Thanks @kurkle! I didn't remember about this change and never updated this plugin accordingly. Is it safe to simply replace beforeInit by install without introducing breaking change?

But as the plugin is disabled with { display: false }, it should be called.

Indeed, display: false only "hides" the labels, all hooks still get called so should not skip beforeInit.

kurkle commented 1 year ago

Is it safe to simply replace beforeInit by install without introducing breaking change?

That is the idea. I'm not aware of any plugin doing that in a minor version thought, so I don't have any proof.

ggthename commented 1 year ago

I think it is about initialization problems It was solved by moving import and ChartJS.register from each chart.tsx to _app.tsx and registering them only once.

BDunham484 commented 1 year ago

^^^^^Thanks!!!!

anas012 commented 1 year ago

I have an angular application that shows error Cannot read properties of undefined (reading '_listened'). I have a chart in one component and I am using charts js data labels in plugins array and it is working fine in this component the issue is in the dashboard component in this component I am also using charts but i don't want to show data labels so i added these lines options: { Screenshot_1

  plugins: [
    {
      datalabels: {
        display: false,
      },
    },
  ],
},

but when I reload the screen it gives an error if I added data labels in plugin array then it is fine but it shows data labels and I don't want to display data labels. Can anyone suggest me a solution? Thank you @salmanorak @chiexclusive @fstrazzante @ggthename @kurkle

GerardoTovar commented 1 month ago

I have 3 graphs. 2 with the plugin and one without the plugin. If the graph that does not have the plugin, you add an ngif with a delay of one second, it does not give the error

setTimeout(() => { this.loading = true; }, 2000);

*ngIf="loading"