Find all instance coming from the same component

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? :slight_smile: 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:

2 Likes

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'
1 Like

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'
2 Likes