question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Circular JSON convert exception when clicking barchart bar

See original GitHub issue

Hello, I’ve recently dabbled a bit on how to use certain plugins in combination with this project (specifically the datalabels plugin).

Disclaimer: there is a good chance you have no clue why I am getting these errors, but asking here is worth a try!

My Blazor Service-side project features a fully-fledged barchart with multiple ‘levels’ where deeper (and more detailed) levels can be accessed by pressing on bars in the chart. For example Level 1 -> Year view Level 2 -> Month view Level 3 -> Day view Level 4 -> Hour view.

In my config I add a OnClickHandler


_config = new BarConfig(ChartType.Bar)
                {...},
                        OnClick = new DotNetInstanceClickHandler(OnClickHandler)
                    }
                };

Which is defined as such:


[JSInvokable]
    public void OnClickHandler(object sender, object args)
    {
        
            var clickedLabel = GetClickedLabel(args.ToString());
            if (clickedLabel != "")
            {

                switch (state.CurrentState)
                {
                    case State.Year:
                        state.SelectedYear = clickedLabel;
                        state.CurrentState = State.Month;
                        UpdateGraph(readings.Table1);
                        btnYearClass = "btn-show";
                        this.StateHasChanged();
                        break;
                    case State.Month:
                        state.SelectedMonth = state.GetIndexOfMonth(clickedLabel);
                        state.CurrentState = State.Day;
                        UpdateGraph(readings.Table2);
                        btnMonthClass = "btn-show";
                        this.StateHasChanged();
                        break;
                    case State.Day:
                        if (supplier.ConsumptionDetailLevel > 3)
                        {
                            state.SelectedDay = clickedLabel;
                            state.CurrentState = State.Hour;
                            UpdateGraph(readings.Table3);
                            btnDayClass = "btn-show";
                            this.StateHasChanged();
                            break;
                        }
                        break;
                }
            }
        }
    }

This works perfectly!

The Exception

I have then added a reference to the datalabels plugin for chartjs in my _Host.cshtml <script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@0.7.0/dist/chartjs-plugin-datalabels.min.js"></script> Which results in this chart as I load my chart page: image

Looks fine?

However, whenever I try to click a bar to move to a deeper level, I get this exception:

blazor.server.js:8 Uncaught (in promise) TypeError: Converting circular structure to JSON
    --> starting at object with constructor 'ni'
    |     property 'config' -> object with constructor 'Object'
    |     property 'data' -> object with constructor 'Object'
    |     ...
    |     index 0 -> object with constructor 'i'
    --- property '_chart' closes the circle
    at JSON.stringify (<anonymous>)
    at c (blazor.server.js:8)
    at e.invokeMethodAsync (blazor.server.js:8)
    at ni.<anonymous> (ChartJsInterop.ts:269)
    at ni.handleEvent (Chart.min.js:7)
    at ni.eventHandler (Chart.min.js:7)
    at i (Chart.min.js:7)
    at HTMLCanvasElement.Fe.<computed> (Chart.min.js:7)

Looking at line 269 in ChartJsInterop:

           // .Net instance method
            else if (typeof iClickHandler === "object" &&
                iClickHandler.hasOwnProperty('instanceRef') &&
                iClickHandler.hasOwnProperty('methodName')) {
                return (() => {
                    const onClickInstanceHandler: { instanceRef: DotNetObjectReference, methodName: string } = <any>iClickHandler;
                    const instanceRef = onClickInstanceHandler.instanceRef;
                    const methodName = onClickInstanceHandler.methodName;

                    return async (sender, args) => {

                        // This is sometimes necessary in order to avoid circular reference errors during JSON serialization
                        args = this.GetCleanArgs(args);

                        await instanceRef.invokeMethodAsync(methodName, sender, args);
                    };
                })();
            }
        } else { // fallback to the default
            return chartJsDefaultHandler;
        }
    };

    private GetCleanArgs = (args) => {
        // ToDo: refactor the function to clean up the args of each chart type 
        return typeof args['map'] === 'function' ?
            args.map(e => {
                    const newE = Object.assign({}, e, {_chart: undefined}, {_xScale: undefined}, {_yScale: undefined});
                    return newE;
                }
            ) : args;
    };

There is the GetCleanArgs method to avoid circular reference errors, so it seems something similar has been dealt with before. Any clue whats missing, as I imagine that the datalabels plugin messes with this in some way?

Let me know if you need any additional resources from me.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:6

github_iconTop GitHub Comments

2reactions
larschristensen20commented, Nov 10, 2020

Thanks a lot @Joelius300. At the moment I am busy conducting internal tests on another project, at my work place, so I sadly cannot devote much time to this (yet), I’m hoping I’ll have more time to update to 2.0 as well as provide a sample in December. I’ll stay in touch!

2reactions
larschristensen20commented, Oct 19, 2020

Thanks for your answer @Joelius300 (and work!)

I did figure as much, from looking at some of the older issues 😃 However, I wanted to give it a thorough try as well as confirm my findings with you, so thanks for confirming!

I’ll happily wait for the new features, I’m looking forward to using them once you have them ready. Sadly my project is not open source, so I cannot share the entirety of the source code here, however, I wouldn’t mind providing a sample once I get one to work.

To everyone that stumbles upon this issue, I would rather wait until I can get my fingers on the complete 2.0 release to continue down this path, so for now I will not prioritize getting plugins to work. When 2.0 is released that will be my priority, and I will try to find some extra time to provide a sample on doing so.

Thanks again for your continued devotion to the project @Joelius300 , as far as I am concerned this is the best chart framework for Blazor!

Read more comments on GitHub >

github_iconTop Results From Across the Web

circular structure to JSON in react - javascript
TypeError: Converting circular structure to JSON says the oposite. Inside response.datasets you have _meta , probably there you have circular ...
Read more >
How to fix TypeError: Converting circular structure to JSON ...
One way to do this is to use a library like JSONC that supports converting circular structures to JSON.
Read more >
Circular Reference Error in JavaScript – Meaning and How ...
This error, in my experience, occurs when you try to convert an object with circular references to JSON. You may have experienced this...
Read more >
JSON Parsing in Android using Retrofit Library
Navigate to the app > java > your app's package name > Right-click on it > New > Java class and name it...
Read more >
How to render a Flutter chart using the JSON data ...
Refer the following instructions, to convert JSON data to chart data list using the deserialization concept. Step 1: First, create an assets folder...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found