highcharts / highcharts-angular

Highcharts official integration for Angular
Other
429 stars 116 forks source link

Subsequent render() events are called outside angular. #360

Open wjaspers opened 1 year ago

wjaspers commented 1 year ago

Describe the bug

The initial chart render is run inside angular, while subsequent calls to chart.render() are run outside angular. This can cause problems with async updates in components.

Expected behavior

All calls to render() are run inside angular, unless [runOutsideAngular]="true"

Demo

Stackblitz

Steps required to recreate the problem in the demo:

console.log(NgZone.isInAngularZone())

Setup used

karolkolodziej commented 1 year ago

Hi @wjaspers!

Thank you for raising this issue but I'm not sure if that is the fault of the wrapper.

I've added the chart without it and we get the same results- demo. In the beginning, I thought that is a context issue and I tried function(){} and ()=>{} but the results were the same.

karolkolodziej commented 1 year ago

Any idea what might cause that, I'm not that familiar with isInAngularZone?

wjaspers commented 1 year ago

I presume Highcharts' events should be patched by highcharts-angular or that the wrapper provides some means to bring changes back into Angular's zone.

We only used NgZone.isInAngularZone() to determine if things are happening inside or outside the Angular framework. NgZone should be used in rare circumstances, particularly when another library is acting on the page and changes would affect Angular's own change detection.

In our situation, we need to remove some chart data after it has been rendered and notify the outside. Because this is happening outside the Angular zone, changes made to angular components aren't picked up by the framework until the next lifecycle hook is called.

karolkolodziej commented 1 year ago

The idea behind the highcharts-angular wrapper is to use Angular and its state to handle component changes. And usually, the chart is only reflecting the changes that are in your app.

However, you can create the chart outside of Angular and then the update through the reference is performed in the Angular zone- demo. If I'm missing something, please show me your use case (how and when you perform that update) so I can properly understand what you are dealing with.

wjaspers commented 1 year ago

My apologies for my late reply; Ill try to get you a semi-functional demo or at least an example as soon as I can.

The update I need to make has to be inside Angular's change detection so it will be applied at the correct time. Therefore, creating the chart outside Angular would not solve the problem at hand.

karolkolodziej commented 1 year ago

That would be great if you can prepare a demo of what you are trying to do ;)

wjaspers commented 1 year ago

Stackblitz Example

I've minimized how many chart options are actually used to help isolate the issue at hand.

Our example is as such:

karolkolodziej commented 1 year ago

Thank you for the demo and details about your use case!

If you use the runOutsideAngular and then if you update the chart component (not the instance) it works as intended- demo.

PS I was not fully able to run your demo which is why I've created a separate one.

wjaspers commented 1 year ago

I see that I made a mistake in my stackblitz, which I need to fix. However, all calls to Highcharts.render should be inside or outside angular, respective of the runOutsideAngular option.