6

I submitted a lightning component to the Security Review. They reported an issue regarding Illegal DOM Access.

I used the following code in my helper and security review team reported it has an issue.

function setDuration(sld, flag, duration) {
    if(flag) {
        if(!duration) {
            duration = helper.default_duration;
        }
        return window.setInterval(function(){
            sld.next(sld.current + 1); //Switch to the next item on regular interval.
        }, duration);
    }
}

The reason they gave us is below:

Components are allowed to touch only their own DOM. The exception is the window object, which is used in this helper. If the component is setting events to Window, it needs to

  1. clean itself up on re-render and
  2. verify that the component still exists when the event fires

To solve the second point is to check the component is valid or not. So I modified the code as below.

function setDuration(sld, flag, duration, component) {
    if(flag) {
        if(!duration) {
            duration = helper.default_duration;
        }
        return window.setInterval(function(){
            if(component.isValid()) {
                sld.next(sld.current + 1); //Switch to the next item on regular interval.
            }
        }, duration);
    }
}

But I could not understand what they are telling in the first point. Any help will be appreciated.

  • Where are you calling the function? Is it in re-render? Use $A.getCallback() to wrap any code that modifies a component outside the normal rerendering lifecycle. Please check developer.salesforce.com/docs/atlas.en-us.lightning.meta/… () – SE_User Aug 18 '16 at 12:44
  • Earlier it was called from the controller. Now I changed it to afterRender. There is no component specific action like component.set() or component.get() in the function. So I think using $A.getCallback is not neccessory. – Melbin T Aug 18 '16 at 12:57
8

You are calling a loop with setInterval. This loop will continue to run because it is attached to the window, but the lifecycle of your component is not the life cycle of the window. E.g. if your component is unrendered, say because a user closes the tab in which your component was running, the window object will still be there running that interval long after your component is gone.

That's why you should clean up by calling clearInterval when your component is unrendered, and that's something you can do in a custom unrender() handler -- which is where you would put the rest of your other clean up code.

Isolation issues such as these are a big reason for the introduction of LockerService, as most developers assume that their code will live with the same lifecycle as window, and are used to having the browser take care of cleanup for them. LockerService shadows window and gives you access to your own version of it, SecureWindow, which will have the lifecycle of your component, at which point you can go back to pretending that you own window and call 'setInterval' without worrying about your loop continuing to run after your component has been removed from the page.

| improve this answer | |
  • We also thought the same. Thank you for corfirming it. – Melbin T Aug 19 '16 at 6:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.