Skip to main content
JosephxBrick
Active Member
February 4, 2023
Solved

API: how best to determine whether a node can have children

  • February 4, 2023
  • 6 replies
  • 1421 views

Hi!

A lot of my code (usually typed into the Scripter plugin) walks though what’s selected on a page, and if a selected node has children, I also want to look inside of that node to find what I’m looking for.

What is the best way to determine, code-wise, whether a node can contain children? Here is the method I use, which seems pretty hacky at best:

const selectedNodes = figma.currentPage.selection as any[];
for (const selectedNode of selectedNodes){
  // find out if selectedNode can contain children
  if ('|FRAME|GROUP|SECTION|COMPONENT|COMPONENT_SET|INSTANCE|'.includes(`|${selectedNode.type}|`)){
    selectedNode.findAll(...)

Is there a better way?

This topic has been closed for replies.
Best answer by Gleb

I wouldn’t recommend using if (node.children) as it would be falsy even if children array exists but has the length of zero. (node.children.length === 0)

To check whether something is defined you can use if (typeof node.children !== 'undefined'). However that wouldn’t work if the property can be set to undefined, so it wouldn’t be the best solution in all cases. Only use it to check if a property is undefined, not if the property exists.

To check whether the property exists on the object, use if ('children' in node) — this way you can be sure you can read the value of this property.

And trust me, even if these differences seem small, it’s very easy to get caught on these when you continue working on the plugin and it doesn’t work correctly for some reason. Being explicit with what exactly you want to check is a good practice.

6 replies

tank666
February 4, 2023

Instead of an array of node types, you can use the following condition: if (node.children) {…}.

UX/UI designer. Figma expert. Creator and developer of plugins and widgets for Figma and FigJam. Check out my resources in Figma Community: figma.com/@tank
JosephxBrick
Active Member
February 4, 2023

Bam! Works like a champ. I guess I needed a reminder that ‘undefined’ is a falsy value. Thanks!

Gleb
GlebAnswer
Power Member
February 5, 2023

I wouldn’t recommend using if (node.children) as it would be falsy even if children array exists but has the length of zero. (node.children.length === 0)

To check whether something is defined you can use if (typeof node.children !== 'undefined'). However that wouldn’t work if the property can be set to undefined, so it wouldn’t be the best solution in all cases. Only use it to check if a property is undefined, not if the property exists.

To check whether the property exists on the object, use if ('children' in node) — this way you can be sure you can read the value of this property.

And trust me, even if these differences seem small, it’s very easy to get caught on these when you continue working on the plugin and it doesn’t work correctly for some reason. Being explicit with what exactly you want to check is a good practice.

tank666
February 5, 2023

I would like to correct, it would return true, not false.

UX/UI designer. Figma expert. Creator and developer of plugins and widgets for Figma and FigJam. Check out my resources in Figma Community: figma.com/@tank
Gleb
Power Member
February 5, 2023

Oh, true. I guess I mistook this for what happens when using loose equality operator (==). P.S. If any beginners are reading this, you should never use ==.

JosephxBrick
Active Member
February 7, 2023

Thanks Gleb –

Here I just want to know it the node can have children, so I don’t get an error when I try to access them. So your suggestion of (‘property’ in object) solves it for me. It also doesn’t doesn’t induce a type warning out of my IDE like (node.children) does, considering some nodes in the array may not support children.

If I’m staying within the guardrails of the Scripter plugin, I notice I can call isContainerNode() from the Scripter API. There is other nice functionality in the Scripter API that would be handy to have in general.