2

I am trying to call a controller function from a regular html button. However, I am having a hard time getting access the the controller.

I have this:

<button id="btn">My Button</button>

I have this from the scripts loaded function:

scriptsLoaded: function(component, event, helper) {
  new myClass(controller, helper);
}

Then is a static Javascript library I have:

var myClass = (function() {
  function myClass(controller, helper) {
    this.controller = controller;
    this.helper = helper;
    this.helper.doAction(this.controller);
    $("#id").click(function() { 
        this.helper.doAction(this.controller);
    });
  }
));

Finally in my helper I have:

doAction: function(controller) {
        var action = component.get("c.fetchData");
    action.setCallback(this, function(response) {
            // Never reach here from click handler
            var returnResponse = response.getReturnValue();
            console.log(returnResponse);
            broadcastEvent("SalesPlanEventTypes_fetchData", finalResult);
    });
    $A.enqueueAction(action);
}

As you see, I store the controller in an intermediate object, then, hook up the event handler to reuse that controller to make the action call in the helper function.

However, although the call works the first time, it does not work in response to the button click -- that is to say the action callback is never called.

3

It looks like you meant:

$("#btn").click(function() { 

You need to make sure that the ID matches what you're querying.

As an aside, I wouldn't use jQuerry for this purpose; it'd be much better to use native Lightning code for this purpose.

0

Note that using the standard pattern for this logic reduces the controller code to this (and keeps all code within the component itself):

myButtonClick : function(component, event, helper) {
    helper.doAction(component);
},

if you make the button a Lightning Component e.g.:

<lightning:button label="My Button" onclick="{! c.myButtonClick }" />

So you a strong reason is needed to not use the standard pattern.

Also significantly this standard pattern ensures that there are no DOM id clashes in the page. Your present solution has:

... id="btn" ...

which means the page will be broken if more than one instance of your component is in the page or if some other component also has the same id hard coded.

+1 for avoiding jQuery. That temps you to fallback on patterns that are not appropriate in Lightning Components, especially now that LockerService often blocks DOM access.

2
  • The problem is that the Javascript is inserted dynamically, so the button is created by Javascript. This works just fine under LockerService, but any Aura code is not parsed when we do that. So somehow I need to access the controller without this standard pattern.
    – Fraser Orr
    May 13 '18 at 15:20
  • @FraserOrr OK. I've done a fair bit of $A.createComponent stuff connecting the dynamically created Lightning Components to pre-existing controller methods by using component.getReference. (A good thing about Lightning Components is that you can choose between declarative and code created components.) So my suggestion is to be absolutely sure the platform can't do what you want before creating your own patterns.
    – Keith C
    May 13 '18 at 17:42

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.