Preserve object properties when cloning and when those properties have getters/setters
See original GitHub issueExpected Behavior
When a non-standard property is included with options
, that non-standard property is cloned in such a way that its properties are preserved on the object, even when its properties feature getters and setters.
Current Behavior
When a non-standard property of options
has getters and setters, the clone
helper method does not preserve that property’s keys on the property itself - instead, it only copies them to the property’s prototype.
This appears to stem from a change that was made in 2.9.4. The method of cloning an object was modified, such that it now utilizes Object.create()
, which copies the properties from the source object into the target object’s prototype. This is a problem if an object’s properties includes getters and setters (which would include, for example, any Vue.js observer); as per https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain:
Setting a property to an object creates an own property. The only exception to the getting and setting behavior rules is when there is an inherited property with a getter or a setter.
Possible Solution
It seems like the suggested solution in https://github.com/chartjs/Chart.js/issues/7340 (a related PR of which led to this issue) should be sufficient.
Steps to Reproduce
Please see https://codepen.io/nb1987/pen/LYbGzNW - in particular, the non-standard properties added to options
. From the console log, you can see that Object.keys(myChart.options.nonStandardProp)
returns ['a']
, but Object.keys(myChart.options.nonStandardPropWithGettersAndSetters)
returns an empty array.
Context
I am using https://github.com/apertureless/vue-chartjs and https://github.com/chartjs/chartjs-plugin-annotation, and the annotation plugin is not working due to this issue. It is easy enough to fix the issue by ensuring that the non-standard option (in this case, annotation
) is supplied as a POJO instead of as a Vue observer (e.g., using Object.assign({ }, options)
), but it’s a problem that could potentially affect users outside the context of Vue and the chartjs-plugin-annotation.
Others have reported the issue at:
- https://github.com/apertureless/vue-chartjs/issues/666
- https://github.com/chartjs/chartjs-plugin-annotation/issues/276
- https://stackoverflow.com/questions/64878459/annotation-dont-show-in-vue-chartjs/65769130#65769130.
- https://stackoverflow.com/questions/65825141/annotations-are-not-displayed-in-chart-js
- https://stackoverflow.com/questions/65022623/chart-js-annotations-in-vue-js-break-when-defined-in-data
Environment
- Chart.js version: 2.9.4
- Browser name and version: Chrome 87.0.4280.141
- Link to your project:
Issue Analytics
- State:
- Created 3 years ago
- Comments:6 (2 by maintainers)
Top GitHub Comments
@jastax no there won’t be a version 2.9.5 but the issue says that it is patched in version 2.9.4 so you can use that
up