Get the layer Name: app.activeDocument.layers is not working as use to

using:

     app.activeDocument.layers.forEach(h => console.log(h.name))

does not gives the name if that layer is inside of a group.
it was working fine but stop working

it only shows the name if the layer is out of group
how do i do the same in order to fix my problem?

I see that in the Layers panel there is 2 layers inside of a group and two layers out and inside of the class the activeDocument.layers only see the out layers.it was not like that before.

Not sure how it was before, but according to docs

layers: All the layers in the document at the top level

So it looks like you’ll have to recursively get all the tree yourself.
And I don’t see this in changelog

OK, this might be related:

Adobe Photoshop Prerelease Build 61: Jun 24, 2021

Updated DOM API

  • New Layers collection, the old layerTree object is now called layers but as a collection using the JavaScript Proxy object. See below for introduction of collections. The old layers behavior is no longer part of the DOM. Most scripts can be updated to replace layerTree with layers . A document and a layer, if the layer kind is group, will have a valid layers collection. A pixel layer will have null for the layers property. A collection has the same semantics as an Array. The additional ExtendScript routines of add and getByName are also available. Use LayerKind.GROUP on a layer to see if any layers are available.
  • GroupLayer has been removed. Use activeLayer.kind === LayerKind.GROUP instead.

I already read that information and as I commented if you do the example you will see that.
With Ap2 which was the new thing I did, the same code was workin but after the change it only sees the layers that are outside a group. Test and confirm. please

Why would I test and confirm? Both you and docs say the same, so I trust that is the case. As I mentioned, you will probably have to implement full tree getter yourself. Or maybe someone already has it and will share

This is what I mean. Before updating it worked fine.
As seen in the example, it only shows the name of the group and the black Layer that is outside, but the red one does not see it. if I compile the class it only has 2 elements in the array when before it showed everything.
can someone show me what to do?
and thanks for replying.

@Karmalakas already gave you the answer:

You’re going to need to write a recursive getter function that loops through each top level layer as you are already doing, checking if it is a group layer or not, then looping though any child layers if found (and checking if they’re group layers, etc, etc). All the while you push the found layers to an array which the function’s return value.

i understand. Thanks but
how do i acces if a layer is a group to the child ?

it’s .layers all the way down the DOM.

// example assumes all layers are group layers
const topLevelLayers = app.activeDocument.layers;

for (const topLayer of topLevelLayers) {

    const childLayers = topLayer.layers;

    for (const childLayer of childLayers) {
        const moreChildLayers = childLayer.layers;
    }
}

If you’re asking how to test if a layer is a group layer then @Karmalakas already answered that one too (see last line):

Thank you very much for your help,
Before seeing your code I wrote this:

app.activeDocument.layers.forEach(alllayers => {
if(alllayers.kind == “group”)
{
const al = alllayers.layers[1].name;
app.showAlert(al);
}
});

and it works!
Now I can check if a layer exists within the group. Now I will do what you suggested.
Thanks for the help, very grateful.

Quick suggestion - when you use a loop (forEach in your example) you are passing each individual enumerable into the curly braces one at a time so it’s best to use singular rather than plural terminology. it’ll make your code easier to read.

// "layer" rather than "allLayers" 
// because once inside the loop it is only one layer at a time
// "for each layer... do stuff..."
app.activeDocument.layers.forEach(layer=> {
    if(layer.kind == “group”) {
        const al = layer.layers[1].name;
        app.showAlert(al);
    }
});

Ok. Tthanks!

very well done notations.

Couple of suggestions:

  • Learn how to use UDT and Debug Console instead of alerts - this will make your development so much easier
  • Please use backticks here in posts to wrap your code

Single for inline:

`// codeLine`

Tripple for block:

```
// codeBlock
```

thanks Kamalakas
i will do so.

It’d be good to use the Ps constants here. (See Important Updates for UXP Powered Photoshop Plugins | by Kerri Shotts | Adobe Tech Blog)

const { LayerKind } = require("photoshop").constants;
/*...*/
if (layer.kind === LayerKind.GROUP) { /* ... */ }
1 Like