Lightning component.find(“aura:id”) returns an array consisting of one element

I found the following excerpt in the documentation:

  • If the local ID is unique, find() returns the component.
  • If there are
    multiple components with the same local ID, find() returns an array
    of the components.
  • If there is no matching local ID, find() returns
    undefined.

In my case lightning component.find(“aura:id”) returns an array consisting of one element. How is that possible? Should not it have returned a single element instead?

I am sorry I can not provide the verifiable piece of code, because there is a lot going on there. I am just interesting, maybe someone else had the same problem and will be able to share the reason it happened to one and how you could guarantee to always get either an element or an array.

I will try to provide some code.

Here is what happens when the component loads:

onInit: function(component, event, helper) {
    const flowId = "a091r00001Z4GRyAAN";
    $A.createComponent(
        "zced:RPGFlowComponent",
        {
            "aura:id": "interactionsGraph",
            "flowId": flowId
        },
        helper.setUpperRightComponent(component)
    );
}

setUpperRightComponent: function(component) {
    return function(newComponent, status, errorMessage) {
        if (status === "SUCCESS") {
            const rightUpperPart = component.find("rightUpperComponent");
            const body = [];
            body.push(newComponent);
            rightUpperPart.set("v.body", body);
        }
        else if (status === "INCOMPLETE") {
            console.log("INCOMPLETE")
        }
        else if (status === "ERROR") {
            console.log("ERROR: " + errorMessage);
        }
    }
}

It just creates another component inside itself with aura:id being set to interactionsGraph.

And when I try the following code after the initialization:

const graph = component.find("interactionsGraph");

the graph is equal to a signle object. Here the component refers to the same component which called the onInit above.

But if at some point after initialization I run the following code:

updateRPGFlowGraph: function(component, event, helper) {
        event.stopPropagation();

        let refreshTweakerMenu = event.getParam("refreshTweakerMenu");
        if(refreshTweakerMenu !== false) {
            refreshTweakerMenu = true;
        }

        $A.createComponent(
            "zced:RPGFlowComponent",
            {
                "aura:id": "interactionsGraph",
                "flowId": event.getParam("flowId"),
                "selectedInteractionId": event.getParam("selectedInteractionId"),
                "refreshTweakerMenu": refreshTweakerMenu
            },
            helper.setUpperRightComponent(component)
        );
    }

then after running

const graph = component.find("interactionsGraph");

the graph will be equal to an array consisting of one object. The object is correct, in other words exactly the object I am expecting. But again the problem is that I would not like to create a crutch and check every time whether it is an array or an object.

UPDATE

Let us take a look at this part of code:

const rightUpperPart = component.find("rightUpperComponent");
const body = [];
body.push(newComponent);
rightUpperPart.set("v.body", body);

After executing the code we are definitely left with only one component which has the specified aura:id. And while we were executing the code there was no moment in time when we had two components with the same aura:id. As I understand it, we take a new component and put it in the place of the old one immediately.

So, now after running the code:

const graph = component.find("interactionsGraph");

I am expecting the graph to be a single object. Will the object property corresponding to the aura:id be preserved even if the component was deleted?

In other words if I had a component with aura:id being equal myCustomId that means that I had a map myCustomId : myComponent. Now I delete the myComponent, but still when I create a new component with the aura:id being equal myCustomId it will check that there is a key in map and so will create an array instead of putting a single object. Am I right?

Answer

The reason only one item could be returned as the result of a find() call is that we keep a map of ID to component in our services.

"myId": "1:0"

If you register two components with the same ID, we convert it to an array.

"myId": ["1:0", "42:0"]

If you then destroy one of those components, it stays an array.

"myId": ["1:0"]

I do think there might be a bug on this, but I’m just here explaining what happened.

Attribution
Source : Link , Question Author : iloveseven , Answer Author : Kris Gray

Leave a Comment