[SalesForce] Lightning Component – Locker Service Issue

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:
enter image description here

Break point added to show the stack-trace message
enter image description here

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:

var concreteHelper = cmp.getConcreteComponent().getDef().getHelper();

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:

<aura:method name="myMethod" action="{!c.myMethodHandler}"/>

And call it from the super component:

component.getConcreteComponent().myMethod();

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.

Related Topic