Skip to main content
Solved

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

  • February 4, 2023
  • 6 replies
  • 1162 views

JosephxBrick

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?

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.

View original
This topic has been closed for replies.

6 replies

tank666
  • 4873 replies
  • February 4, 2023

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


JosephxBrick
  • Author
  • New Participant
  • 67 replies
  • February 4, 2023

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


Gleb
  • Power Member
  • 4708 replies
  • Answer
  • 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
  • 4873 replies
  • February 5, 2023

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


Gleb
  • Power Member
  • 4708 replies
  • 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
  • Author
  • New Participant
  • 67 replies
  • 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.


Cookie policy

We use cookies to enhance and personalize your experience. If you accept you agree to our full cookie policy. Learn more about our cookies.

 
Cookie settings