Accessing children of a ComponentNode

Hi

I’m struggling to get access to a ComponentNode’s children. I’m probably missing something, so wondered if someone can help? Thanks in advance!

I’ve tried 2 ways of getting access to the main component. Both appear ok in the console, but when I try and access it’s children I get empty arrays.

    //passed in as a function constructor
    console.log(tableComponent);

    const columns = tableComponent.findChildren(n => n.type === "FRAME");
    
    const findTable = figma.currentPage.findOne(n => n.name === tableComponent.name) as ComponentNode;

    const columns2 = findTable.findChildren(n => n.type === "FRAME");

    console.log(findTable);

    console.log(columns.length);
    console.log(columns2.length);

1

Turns out I was running my function too early. I’d only just appended the component I was looking for. Using simple awaits wasn’t enough.

I’ve had to apply the following code to wait for the node. Is there a better way of managing this?

async function waitForNode(nodeId: string) {
  return new Promise<ComponentNode | FrameNode>((resolve, reject) => {
    const interval = setInterval(async () => {
      try {
        const node = await figma.getNodeByIdAsync(nodeId) as ComponentNode | FrameNode;
        if (node && 'children' in node && node.children.length > 0) {
          clearInterval(interval);
          resolve(node);
        }
      } catch (error) {
        clearInterval(interval);
        reject(error);
      }
    }, 10); // Check every 10ms
  });
}

What exactly are you trying to achieve with your code? The code in the original post doesn’t seem related to the waitForNode function. And it has a redundant findTable variable — you already have tableComponent, why search for it again? In the waitForNode function, why are you searching for the same node with specific ID every 10 ms? The id is not gonna change, the node isn’t gonna appear out of nowhere. All of this looks very strange.

As for the original question:

You get the array of children via component.children and then you can do whatever you need with this array.

This giving you 0 means there are no frames that are direct children of the componentNode, maybe you’ve got groups in it instead or instances or other objects?

Believe me, it all feels weird and hacky. As you say I should be able to easily access the children of the ComponentNode, but I’ve had to hack it for some reason to get access to the children.

These are the function calls I’m having to use.

    const tableComponent = await createTableComponent(tableName, columnData, numRows);
    const readyTableComponent = await waitForNode(tableComponent.id);
    adjustRowHeights(readyTableComponent as ComponentNode);

My first attempt was simply to call adjustRowHeights straight away after tableComponent was returned. The createTableComponent creates a table and appends it to the page. But without the waitForNode ‘hack’ I just wasn’t able to access the children. Once that was added it worked fine.

If I had to guess what’s happening, it’s that when you create the table component, the children are being added async and aren’t being properly awaited, which leads to you having to wait for children to appear. So if you share what createTableComponent is doing, that might clear things up.

As Gleb said, you just need component.children:

const component = figma.createComponent()
component.appendChild(figma.createFrame())
console.log(component.children) // Output: [FrameNode]
console.log(component.children.length) // Output: 1

Is this piece of code wrapped in an async function? You can’t await outside of async function (does nothing).

Thanks for the responses. Yeah, I’ve checked all my relevant functions are marked with async and all calls are marked with await. It’s a little weird. I’ll keep looking, but suspect it’s not waiting for all the children to be rendered before the I’m running the current function.