1

I worked on lightning component without enabling the locker services. And when I enabled the locker services, I faced an issue with the existing code.

Before enabling the locker services I use this method

//PickupLocationtooltip is aura:id of element

var ele = component.find("PickupLocationtooltip").getElement();

it was working fine. But When I enabled the locker Services, It is giving me an error "rerender threw an error in 'markup://c:AvailableCar' [component.find(...).getElement is not a function]"enter image description here

Please help me to overcome this problem. Let me know if anyone need more information on this.

The markup section : enter image description here

8
  • is PickupLocationtooltip aura:id of a component? Commented May 29, 2017 at 8:26
  • What do you want to achieve with this element ? Commented May 29, 2017 at 8:32
  • yes @ManjotSingh Commented May 29, 2017 at 8:47
  • I want to get this element so that I can edit the properties of this element @FabienTaillon Commented May 29, 2017 at 8:48
  • @TariqueShamim Which properties you want to change? Commented May 29, 2017 at 8:54

2 Answers 2

5

if PickupLocationtooltip is a separate component, then you won't be able to access it's internals with Locker Service enabled.

What you will need to do to perform actions on this component is to either use events to communicate or define a public interface on the PickupLocationtooltip component via an aura:method

If you expose a method, you can call this method on the component and perform your dom manipulation that way - but the component can access it's own dom an no-one else's.

To define a method on the child component do this:

<aura:method name="manipulateDom" action="{!c.manipulateDom}" > 
  <aura:attribute name="param1" type="String" /> 
</aura:method>

To call this method, do this:

component.find("PickupLocationtooltip").manipulateDom("some val");

EDIT

As I can see you have a ui:outputText here, it's a standard built-in salesforce component. You cannot alter it's internals anymore.

However, you could replace it with a <div> or <span> and not notice any difference.

Perhaps just try this:

<div aura:id="PickupLocationtooltip">{!v.yourValue}</div>

Then when you want the value to change, just do this:

component.set("v.yourValue");

You should be doing this anyway - directly setting the innerHTML of components is frowned apon (and now doesn't work in many cases) in Lightning.

7
  • Sorry @CasparHarmer but "PickupLocationtooltip" is the aura:id of a element. Commented May 29, 2017 at 8:52
  • 1
    Can you add this part of the markup in your question? Commented May 29, 2017 at 8:54
  • I have added the markup sections @CasparHarmer Commented May 29, 2017 at 8:59
  • ui:outputText IS actually a component. It's a built in ui namespace component. I'm sorry, but you can't access it's internals anymore with Locker Service. Your best best is to roll your own output text - esp if you don't need much fancy formatting, you could just use a div or span here. Commented May 29, 2017 at 9:01
  • Is this the only way for getting it back on track or any other way. Commented May 29, 2017 at 9:05
1

In addition to the excellent explanation provided by @CasparHarmer, here are some additional details.

Lightning is a component-based framework, and it works hard to implement the concept of encapsulation. That means the internals of a component should not be visible, only its interface. For example, the CSS of a component is scoped in a manner that it doesn't affect other components (parent and siblings).

Here, LockerService completes the encapsulation by making the component "opaque" (black box), and this is why methods like getElement() are not accessible from the outside.

In other words, the component that you retrieve:

var component2 = component.find("PickupLocationtooltip");

Only has the public API, whereas the component that you receive in a controller action, inside a component:

({
   myAction: function(component) { }
})

Behaves more like a this in the sense that it has access to all of the private API of the component.

The encapsulation is not perfect in Lightning, at least util we can leverage native web components and the shadow DOM. However, it's important to work now with the intended boundaries of encapsulation in mind. By doing so, you get all of the benefits of encapsulation:

  • Ease of maintenance (nobody relies on internal implementation)
  • Increased reusability (component has to be self-sufficient)

Now, there are three APIs we use normally to trigger something in a component:

  1. Attributes and functions is the simplest one: you declare an attribute, and you reuse it inside your component. This is achieved declaratively, so it requires no JavaScript:
    <aura:component>
        <aura:attribute name="class" type="String"/>
        <div class="{!v.class}"/>
    </aura:component>
  1. Attributes and method handler is a hybrid technique, in the sense that the consumer of your component do change an attribute declaratively or programmatically to triggers a handler:
    <aura:component>
        <aura:attribute name="class" type="String"/>
        <aura:handler name="change" value="{!v.class}" action="{!c.handleClassChange}"/>
    </aura:component>

And a controller method does the work:

({
    handleClassChange: function(component, event, helper) { 
        var newClass = event.getParam("value");
        var oldClass = event.getParam("oldValue");
        /* do something */ 
    }
})
  1. Method and method handler is a programmatic technique, in the sense that the consumer of your component must use JavaScript programmatically to trigger a handler:
    <aura:component>
        <aura:handler name="changeClass" action="{!c.handleClassChange}"/>
            <aura:attribute name="l" type="String"/>
        </aura:handler>
    </aura:component>

Again, a controller method does the work, but receives the values as “arguments”:

({
    handleClassChange: function(component, event, helper) { 
        var args = event.getParam('arguments');
        var class = args.class;
        /* do something */ 
   }
})

You can read more about these and other techniques here:

https://developer.salesforce.com/blogs/developer-relations/2017/04/lightning-inter-component-communication-patterns.html

2
  • 1
    Very nice explanation @JFParadis - Mine was much less elegant, although infomation provided as I got further in changed the situation somewhat... Commented May 29, 2017 at 18:01
  • 1
    Thanks @CasparHarmer, but I very like your explanation. Sometimes being concise and to the point is better. Now, visitors have two comaptible explanations, and they can look at things from two different angles!
    – JF Paradis
    Commented May 29, 2017 at 19:06

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .