0

I have a series of screens, each screen is a lightning component, dependant on the answers you go to different screens. I an loading the screens dynamically.

I am using this code to dynamically inject custom Lightning components.

injectComponent: function (cmp, name) {

    var self = this;
    var activeScreen = cmp.find('activeScreen');

    if (activeScreen) {
        activeScreen.destroy();
    }

    var target = cmp.find('main');

    $A.createComponent(name, {
        "aura:id": "activeScreen"
    }, function (contentComponent, status, error) {
        if (status === "SUCCESS") {
            target.set("v.body", []);
            target.set('v.body', contentComponent);

            var newCmp = cmp.find('activeScreen');

            if (newCmp) {

               var info = newCmp.get("v.info"); // access attribute
               newCmp.loadData(data); // call component method

            } else {
               // newCmp is null
            }

        } else if (status === "INCOMPLETE") {
            console.log("No response from server or client is offline.")
        } else if (status === "ERROR") {
            console.log(error);
            throw new Error(error);
        }
    });
},

Variable newCmp is always null.

But the component does load and display.

I need to call some methods and access some attributes in the component.

var info = newCmp.get("v.info"); // access attribute
newCmp.loadData(data); // call component method

How can I access the component after creating it?

3

You have at least two potential problems.

body Not Array

An attribute with Aura.Component[] always needs an array. Failure to do so may cause rendering issues. The fix is simple:

target.set('v.body', [contentComponent]);

Not Yet Rendered

Setting the body attribute basically tells the system it needs to render (a part of) the DOM, but these actions are queued up until after your callback completes. As such, component.find can't find the component yet, because it's not part of the DOM.

Instead, just use the contentComponent directly:

if(contentComponent) {
  // Do stuff here

Edit: Based on chat room commentary:

The problem was assuming that the methods that were being called were needed. Instead, the attributes can be assigned during creation time:

$A.createComponent(name, {
    "aura:id": "activeScreen", "data": component.getReference("v.data")
}, function (contentComponent, status, error) {

This allows the component to handle loading its own data during init, removing the need for this particular question to begin with, since it was only needed to call aura:method functions to load the data post-initialization.

7
  • Thanks. Is there a way for find out when the component has rendered, such that the rest of my code can access it? – Robs Jun 13 '18 at 13:17
  • @Robs You should be able to access the component any time after afterRender has fired in your component. You could write a custom renderer to know when the component is available. Honestly, though, I suspect your question may be an X-Y Problem. There should likely be a way to do what you're trying to do without resorting to a custom renderer. Maybe ask a question about what you're trying to do (the X) instead of a solution (the Y)? – sfdcfox Jun 13 '18 at 13:21
  • I've added to the question. I would like to access attributes and call JavaScript methods on the component once it's loaded. The attributes are less important, because I have other ways to get that data, but I call the method and pass in data. – Robs Jun 13 '18 at 13:33
  • @Robs contentComponent gives you access to the component in the callback function. By the time your callback is called, contentComponent will have already processed its aura:valueInit handler, if any, so you should be able to access its attributes. Does that help? – sfdcfox Jun 13 '18 at 14:02
  • RE your X-Y Problem comment, I'd like to ask you about the best approach to solve my problem, could we speak in a chat room, or would you prefer I asked a separate question? – Robs Jun 13 '18 at 15:45

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.