I have an application which depends on outbound calls to REST APIs to fetch data. Is there a way to enqueue and process actions right away? It seems like if I enqueue an action, it is not processed until an event occurs in the rendering lifecycle (text changes, component not visible). I need to be able to click a button on the component to call a server-side action, then get the returned data and make changes to the component based on its return.

Here is some code!

<aura:component controller="ConversationController">
    <aura:handler event="c:RequireJSEvent" action="{!c.initJS}"/>
    <aura:registerEvent type="c:RequireJSEvent" name="requireJSEvent"/>
    <aura:handler name="init" value="{!this}" action="{!c.doInit}" />
    <aura:attribute name="textcount" type="Integer" default="0"/>
    <aura:registerEvent name="appEvent" type="c:ConversationEvent" />

    <div class="slds-docked-composer__body slds-docked-composer__body--form slds-col slds-grid slds-grid--vertical slds-nowrap">
      <fieldset class="slds-form--compound">
        <div class="form-element__group">
            <!-- <c:PhoneNumberSelector /> -->
          <div class="slds-form-element__row">
            <div class="slds-form-element slds-lookup" data-select="multi" data-scope="multi">
              <label class="slds-form-element__label" style="margin:0px">Recipient</label>
              <div class="slds-form-element__control lookup__search-control slds-grid slds-box--border">
                <div class="slds-grid slds-grow">
                  <input id="lookup-01" class="lookup__search-input slds-input--bare slds-grow" maxlength="10" type="text" aria-autocomplete="list" role="combobox" aria-expanded="true" aria-activedescendant="" placeholder="Enter a phone number." />
                </div>
              </div>
            </div>

          </div>
          <div class="slds-form-element__row">
            <div class="slds-form-element">
                <div style="display:flex;"><label class="slds-form-element__label" for="text-input-01">Message</label><div id="textcounter" class="slds-text-body--small" style="margin-left:auto;text-align: right;">{!v.textcount}/160</div></div>
              <div class="slds-form-element__control">
                <textarea style="resize:none;line-height:1rem;padding:.75rem;" maxlength="160" class="slds-input" type="text" id="message-input"  />
              </div>
            </div>
          </div>
        </div>
      </fieldset>
      <div>
        <button class="slds-button slds-button--brand slds-float--right" onclick="{!c.submit}">Send Message</button>
      </div>
    </div>
</aura:component>

Javascript:

({
    doInit: function(cmp, event, helper) {
        if (typeof require !== "undefined") {
            var evt = $A.get("e.c:RequireJSEvent");
            evt.fire();
        } else {
            var head = document.getElementsByTagName('head')[0];
            var script = document.createElement('script');

            script.src = "/resource/RequireJS";
            script.type = 'text/javascript';
            script.key = "/resource/RequireJS";
            script.helper = this;
            script.id = "script_" + cmp.getGlobalId();
            var hlp = helper;
            script.onload = function scriptLoaded() {
                var evt = $A.get("e.c:RequireJSEvent");
                evt.fire();
            };
            head.appendChild(script);
        }
    },

    initJS: function(cmp, event, helper) {
        require.config({
            paths: {
                "jquery": "/resource/jquery?",
                "jquerymask": "/resource/jqueryuimask?"
            }
        });
        console.log("RequiresJS has been loaded? " + (require !== "undefined"));
        //loading libraries sequentially
        console.log("load jquery");
        cmp.set("v.loaded", "True");
        require(["jquery"], function($) {
            console.log("jQuery has been loaded? " + ($ !== "undefined"));
            cmp.set("v.loaded", "True");
            require(["jquerymask"], function() {
                $A.run(function() {
                    helper.inputProcess(cmp);
                });

            })
        }); //require end   
    },

    addOnChange: function(cmp, event, helper) {
        helper.inputProcess(cmp);
    },

    submit: function(cmp, event, helper) {

        var action = cmp.get("c.getMessagesByConversationId");
        action.setParams({
            ConvoId: message
        });
        action.setCallback(this, function(response) {
            var state = response.getState();
            var messages = response.getReturnValue();

            if (state == "SUCCESS")
                cmp.set("v.messages", messages);
            else if (state === "ERROR") {
                var errors = response.getError();
                if (errors) {
                    if (errors[0] && errors[0].message) {
                        console.log("Error message: " +
                            errors[0].message);
                    }
                } else {
                    console.log("Unknown error");
                }
            }
        });
        $A.enqueueAction(action);


        var appEvent = $A.get("e.c:ConversationEvent");
        var convoId = cmp.get("v.convo").Id;
        console.log(event.target);
        console.log(convoId);
        appEvent.setParams({
            "message": convoId
        });
        appEvent.fire();
    }
})

The submit function would be responsible for interacting with the controller and getting return data. This return data would be dependent on results from a callout on the server side controller.

  • 1
    Can you please share some code ? – Mohith Shrivastava Apr 5 '16 at 23:58
  • @MohithShrivastava Added some code – Jason Lee Apr 6 '16 at 3:13
  • I am really not sure why you are complicating entire thing here .You can simply make a REST call with apex aura enabled class and once response is returned you can manipulate DOM or create your own dynamic components . – Mohith Shrivastava Apr 6 '16 at 3:39
  • @MohithShrivastava The issue is the time it takes for the whole process to be finished because the action gets queued. How can I make a queued action process right away instead of waiting for a UI event? – Jason Lee Apr 6 '16 at 3:45
  • When the action is in init call it gets executed as soon as it recieves response from server . If you an attribute binded to UI the framework will wait for your UI update .So you may try doing all in the init call itsle – Mohith Shrivastava Apr 6 '16 at 3:51

I fixed this by making the enter fire an event instead of directly queuing an action. So, 1. User types into text area 2. User presses enter 3. Event is fired 4. Event handler queues action 5. action is processed immediately 6. callback is returned.

Your Answer

 
discard

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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