It would seem that activeDocument.layers simply doesn’t function properly, and I can’t figure out why.
Code That Works
function WorkingNames() {
const app = require("photoshop").app;
const allLayers = app.activeDocument.layers;
const allLayerNames = allLayers.map(layer => layer.name);
const sortedNames = allLayerNames.sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
for (let bla in sortedNames){
console.warn(sortedNames[bla])
}
}
Code That DOESNT Work
function BrokenNames() {
const app = require("photoshop").app;
const allLayers = app.activeDocument.layers;
//const allLayerNames = allLayers.map(layer => layer.name);
//const sortedNames = allLayerNames.sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
for (let bla in allLayers){
console.warn(bla.name)
}
}
When you inspect the result of allLayers in the debugger for both forms of the function after that line executes, it is an empty array in both cases, yet somehow using the magic allLayers.map(layer => layer.name)
causes allLayers to be populated, and we get the expected output.
What am I doing wrong? Is this a rookie mistake on my part, or a very large bug?
Wow, so much to learn about Javascript! I have never heard of proxies or traps before. They appear to be magic to the untrained eye. Its especially confusing that proxies don’t reveal their data while on a breakpoint and inspecting them after assignment, instead appearing as empty versions of whatever they are “wrapping”. I suppose that might be from some kind of custom trap for an essential function?
I’ll sum up my learning here and provide links to the articles that helped me understand proxy and trap.
A proxy creates an instance (or is it a pointer?) of an object with the primary intention of changing how it’s essential functions work (e.g. enumerate, which is used during for in , and getters and setters, etc.).
And a trap is the actual new function that replaces each essential function. Hilariously, they work well as real-life traps, too.
A handler is the object that contains the traps (which are just functions). When you define a new proxy, you pass in the handler as well, thus creating a trap-riddled fake object.
Simple and clear explanation on both Proxy and Trap
until then you can use: Array.from(app.activeDocument.layers)
which return a normal array of layers
or the following function I created to get ALL LAYERS regardless of “depth”
it accepts one argument : the root of layers
it could be doc’s layers or a group of layers