4

With Summer '17 I was able to dynamically set an onclick event that would fire an aura:method and everything worked just fine. This is the code declared in my controller and loaded during the doneRendering phase (I'm using Select2 to enhance a regular select):

doneRendering: function (cmp, event, helper) {

  ...

  var selectUser = cmp.find("selectUser");

  if (selectUser.isRendered()) {
    var uiSelectUser = $(selectUser.getElement());

    uiSelectUser.select2();

    uiSelectUser.change(function (evt) {
      cmp.set("v.myVariable", evt.target.value);
      cmp.myAuraMethod();
    });
  }

  ...
}

In the component I have:

<aura:handler event="aura:doneRendering" action="{!c.doneRendering}" />

<aura:attribute name="myVariable" type="String" />

<select aura:id="selectUser" name="selectUser">
   ...
</select>

And the method:

<aura:method name="myAuraMethod" action="{!c.myControllerMethod}" />

The method would then call a server side method and do its job.

What is happening with Winter '18 now is that the method is called (I checked with the debugger and console logs, everything seems fine) but "visually" it's like nothing is happening.

The interesting thing is the following: in my component I also have some fields. If I move to any field then, suddenly, the method that was invoked before is actually carried out, like it was queued for a later moment and then executed (although, again, with the debugger all the method lines were evaluated).

The same method executed by some other buttons with events that are "directly wired" works immediately.

I'm also using the component on a vf page through lightning out and have a link that calls the same method in the component and even in that case Winter '18 broke the behaviour: the method is invoked, code is evaluated, but nothing is immediately happening. Again, if I click/move to any of the fields in the lightning component area, then the component processes what was called from the vf page.

  • So... You're using jQuery to bind a change handler directly to a DOM element, which in turn invokes a Lightning method? Seems like an anti-pattern to me. Anyway the jQuery event handler lives outside the Lightning rendering lifecycle so it makes sense that you're seeing the view fail to update. Maybe you need to wrap $A.getCallback around your change handler function? – Charles T Oct 21 '17 at 5:43
  • Why anti-pattern? I can't see any other way to bind the onchange event to the select tag. In normal environment the onchange declared with the tag would be picked by the select2. In Lightning it seems like the select2 isn't "seeing" it. By binding it after the select2 is initialized it's working. I tried the $A.getCallback but unless is coupled with a window.timeout the component is still not updating. If I set the timeout then it is. I repeat, everything worked perfectly fine with Summer '17. I would really love to know what's changed. – shillem Oct 21 '17 at 12:40
  • I hadn't noticed the use of a plugin to enhance the select tag. That explains a bit more what you're getting at. In any case, I don't think there is a clearly defined behaviour of the rendering lifecycle in a circumstance like this where you place an Aura method inside an anonymous callback. So it may just be that they made an optimization which shouldn't have affected anyone working within standard best practices but did affect you. Remember that your jQuery plugin sees the Lightning Locker virtualized DOM and not everything works as expected. – Charles T Oct 21 '17 at 15:09
  • I guess so. For the moment the only solution I came up with was to add an aura:handler name=“change” tag that monitors when the variable value changes and fires the method. And it does work! the variable gets set by the Select2 onchange event, the method is fired and evaluated instantly, the component updates itself. – shillem Oct 21 '17 at 16:04
  • 1
    Glad to hear. If it's a rendering lifecycle issue then it's very similar to what one experiences in AngularJS and such frameworks when a data value monitored by the framework is changed in a way that the rendering framework isn't "listening" to, outside a digest cycle. As a result the data change fails to update the view until something triggers a new cycle. – Charles T Oct 21 '17 at 18:03
1

My bad. Using $A.getCallback() solves the problem. The fact is that these changes are performed outside the framework cycle so I must put them back into it if I want them to work correctly.

So, looking back at the original code the change event should be created like this:

uiSelectUser.change($A.getCallback(function (evt) {
  cmp.set("v.myVariable", evt.target.value);
  cmp.myAuraMethod();
}));
0

With Winter 18 you can't have dynamic javascript or any inline dynamic javascript.

Solution:

Try to save that dynamic code as a separate module or function as a resource/js file and then include that resource file.

You should be ready to go.

  • Thank you for chiming in but there are at least 2 reasons why your solution cannot be the answer: 1) the code in its essence is working, it's just "delayed" in its execution. 2) no dynamic js is actually involved, it's all within the lightning rules for the given scenario (I use 2 libraries - jQuery, Select2 - that are already referenced through static resource, the rest comes from the controller, also as you can see the XML doesn't contain any inline code, but I admit I didn't mention the snippet was coming from the controller, I will change that now) – shillem Oct 20 '17 at 18:08

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.