Hey !
I would like to do something on every instance of a same component, coming from an external library.
Let’s say the component is named “XYZ” and has multiple variants.
I know that I need to use *instance*.mainComponent.parent.name
to get the name of the component, because if not it gives the name of the variant (xxx = xxx, yyy = yyy …)
But when I use it as a search criteria, it’s not working :
const instances = figma.root.findAll( elem => elem.mainComponent.parent.name === "Spec guides");
I get the error :
Error : “findAll” callback crashed: TypeError: cannot read property ‘parent’ of undefined
How to do it properly? 🙂 Thanks !
PS : I tried to use the name of the instance. It’s working, but sometimes we rename the instance so it won’t work in this case…
You need to check if the parent
property exists.
What do you mean?
Of course it exists because when I do a console log of the parent name of each element from the findAll array, I have something.
The findAll
method will return all nodes for you according to the condition. In your example, this would be both ComponentNode
and ComponentSetNode
(local and remote nodes). If the node is remote and this node is a ComponentNode
, then its parent
property will be null
. Hence, you are seeing the above error. To fix this, you just need to write the condition correctly.
That’s correct, parent
is null for remote components.
Also, if you have a component node already, it’s much easier to do componentNode.instances
to get all the instances instead of traversing the document:
figma.com
Sorry, I’m not a developer, so just to be sure I understand :
I don’t understand why you say parent
is null for remote components. For instance, when I do this :
const instances = figma.root.findAll( node => node.name === "xxxxxx");
instances.forEach ( instance => console.log(instance.mainComponent.parent.name));
I obtain the name of the original component, and the original component is not in this file. So this is accessible from where I am.
How can I turn this into a condition ?
You should check parent prop exists before accessing it
const instances = figma.root.findAll( elem => elem.mainComponent.parent?.name === "Spec guides");
however the easiest way as stated James is to retrieve instances directly from your component
const mycomponentNode = figma.currentPage.findOne(n => n.name === "Spec guides")
const instances = mycomponentNode.instances
I tried what you said :
const instances = figma.root.findAll( node => node.mainComponent.parent?.name === "name of the component");
console.log(instances);
But I still get the same error “cannot read property ‘parent’ of undefined”.
For the second solution, it cannot work because the component is not in the file, I only have InstanceNodes here.
Your condition should look like this:
node.mainComponent.remote && node.mainComponent.parent && node.mainComponent.parent.name === 'something'
This is a different route, but you can access a function by searching it with the ⌘ + / menu.
Type in “Instance” and it will show “Select all with same instance”
You’d then be able to modify the properties of all components pretty easily. It will only work on the currently selected page.
This code will be quite brittle because only instance nodes will have a mainComponent
. For other nodes, mainComponent
does not exist.
Also, it is generally not recommended to use find*() functions on the entire document, as it will be slow for large files.
This doesn’t look working for me :
const instances = figma.root.findAll( node => node.mainComponent.remote && node.mainComponent.parent && node.mainComponent.parent.name === target);
console.log(instances);
Error: in findAll: “findAll” callback crashed: TypeError: cannot read property ‘remote’ of undefined
Make sense, maybe not optimal.
node.mainComponent && node.mainComponent.remote && node.mainComponent.parent && node.mainComponent.parent.name === 'something'
Thanks a lot, this works. So if I understand, I need to check that all the values exists in any case.
I just want to point out that optional chaining makes this a lot nicer:
node.mainComponent?.remote && node.mainComponent.parent?.name === 'something'