I'm using d3.min.js library in my org. These libraries are being used in lightning component context. this is all working fine till now. After enabling locker service feature it stopped working. Getting below error msg:
Uncaught Error during init [Action failed: c$BaseChartComp$controller$initComponent [TypeError: concreteComponent.getDef is not a function]]
Uncaught TypeError: Cannot set property 'innerHTML'
/resource/D3_3517/D3_3512/d3.min.js:5 Uncaught TypeError: Cannot read property 'document' of undefined
Cannot set property 'innerHTML' of null
Uncaught TypeError: Cannot read property 'matches' of null
Uncaught TypeError: Cannot set property 'innerHTML' of null
Code Snippet which causes the issue:
getConcreteCompHelper: function(component) {
var me = this,
concreteComponent = component.getConcreteComponent(),
ccHelper = concreteComponent.getDef().getHelper();
return ccHelper;
},
getConcreteComp: function(component) {
var me = this,
concreteComponent = component.getConcreteComponent();
return concreteComponent;
},
handleWindowResize: function(component) {
var me = this,
ccHelper = me.getConcreteCompHelper(component),
childComp = me.getConcreteComp(component),
chartRedrawListner = function(cc) {
return function() {
ccHelper.drawChart(cc);
}
},
listener = chartRedrawListner(childComp);
window.addEventListener('resize', listener);
me.windowUnregisterFn = function() {
window.removeEventListener('resize', listener);
}
}
Application is erroring out while executing line,
ccHelper = concreteComponent.getDef().getHelper();
Adding screenshot of error message:
Break point added to show the stack-trace message
Any help would be appreciable.
Best Answer
This seems unrelated to the JS library you are using. What is most likely happening is the following: a parent component is trying to call a child helper using the verbose approach:
We want to remove access to this API because it exposes the complex internal structure of the component. It's hard to test, and hard to maintain.
You need to remove the
.getDef().getHelper()
and replace it with something else. The trick is to declare a method on your concrete component:And call it from the super component:
In Lightning, every level of inheritance creates a component. This is a better pattern, since the helper is not part of the public API of a component like a method. You can define the method on an interface and ensure every instance abides to the contract, something that the
.getDef().getHelper();
was not allowing.