Help with async functions needed

HI I am new to UXP and async functions in JavaScript. I am trying to convert some of my express script code to use UXP. I have the following function:
async function removeLayerComp(compList, compName){
var found = false;
var numElements = compList.length;
for (var count = 0; count < numElements; count++){
compLayer = compList[count];
CLname = compLayer.name;
console(CLname);
if(CLname == compName) {
await compLayer.remove();
found = true;
return found;
}
}
return found;

compLIst is a list of LayerComps from the current document, compName is the name of a Layer Comp I want to remove. When I run the function, it finds the correct Layer Comp by its name but when I go to remove it, it doesn’t. What am I missing?

Thanks
Bill

I’m not an expert. I just a guy playing around the UXP

But did you try to put it in the try-catch? and see the log?

If you see any error log related, then

And since this interacts with the document I think it needs to be put in the executeAsModal() ?

I have prepared removeLayerComp1, which is similar to your code, and removeLayerComp2, which is simpler.

Please pay attention to the points written as comments.

const { app, core } = require('photoshop') ;

async function removeLayerComp1(compList, compName) {
  let found = false ;
  
  // Loop in reverse order as the index changes when an item is removed
  let numElements = compList.length ;
  for(let count = numElements - 1 ; count >= 0 ; count--) {
    const compLayer = compList[count] ;
    const CLname = compLayer.name ;
    console.log(CLname) ; // Use `console.log` instead of `console`

    if(CLname === compName) {
      await compLayer.remove() ;
      found = true ;

      /*
        Remove the `return` that was here to make it a function to remove multiple layer comps with the same name. 
        There is no need to use looping unless that is the purpose
      */
    }
  }
  
  return found ;
}

// You can also use `getAllByName`, `Promise.all`, and `map`
async function removeLayerComp2(doc, compName) {
  const compList = doc.layerComps.getAllByName(compName) ;
  // Returns Array<LayerComp>, not LayerComps

  await Promise.all(compList.map(async (compLayer) => {
    return compLayer.remove() ;
  })) ;

  const found = Boolean(compList.length) ;
  return found ;
}

// Note that `executeAsModal` is required to make changes to the document
core.executeAsModal(async () => 
  {
    const doc = app.activeDocument ;
    const targetCompName = 'Layer Comp 2' ;
    let found ;

    found = await removeLayerComp1(doc.layerComps, targetCompName) ;
    // found = await removeLayerComp2(doc, targetCompName) ;

    await app.showAlert(found) ;
  }, 
  
  {
    commandName: 'Remove Layer Comp', 
    interactive: true
  }
) ;

Frequency - thank you for your suggestions, all good ones. I have been out of the programing world for a while. But back in my code writing days I was really into capturing exceptions as you suggested (just haven’t gotten around to refreshing my memory on how to do that, but it is on my list of things) Also have not had to deal with async functions very much in the past so am not that familiar with modal operations (again researching how this stuff fits together). i definetly focus on the areas you suggested. Thanks Bill

stk3, Thank-you for spending the time to in writing some code suggestions and associated explanations. I have had some experience in java script (as well as many programming languages) in the past but have not dealt with async functions much. I have been retired for a few years and before that I had taken on more of a management role in the programming environment and am having to brush up my programming skills. I am still unclear on when the implementation of executeAsModal is required. As an example, what I posted was some code I was using to remove a pre-existing Layer Comp and replace it with a new one of the same name. Here is the logic I was using to Add the new layer comp

AddLayer Comp

  • Get the Photoshop Document and associated Layer Comps
  • Check to see if a layer comp by that name is currently in the document
  • {note because of some earlier mistakes I made in the past, I found layer comps of the same name might exist - my code needed to ensure all layer comps of that name were removed - your example made me think of a better way to do that now)
    - After the removing the layer comp if it existed I add a new layer comp with the same name by doing an CompList.add(name, …)

So, If I have all the code in the same file, I will be calling at least two async methods, so I am sure my next question is in the core.executeAsModal function how I account for the two different methods.

My other question is if there are two layer comps with the same same name what does getAllByName return, just the first one or an array of all with the same name? Thanks again for you very helpful suggestions Bill

stk3 Thanks again for your help. I am still unclear on where to put the core.executeAsModal function so here is a more complete example of my code: The purpose is to save the current visibility of the Layers in photoshop upon a button press. It then looks for LayerComps with the name associated with the button and removes them before adding a new layercomp with that name.
async function removeLayerComp(compList, compName){
var numElements = compList.length;
lComp = compList.getAllByName(compName);
// above may return array of more than one LayerComp
// remove all of them
numLComps = lComp.length;
if (numLComps > 0){
for (var count = 0; count < numLComps; count++ ){
await lComp[count].remove();
}
}
}
function createLayerComp(compName){
const app = require(“photoshop”).app;
const compList = app.activeDocument.layerComps;
// First Remove Layer Comps of same name if they exist
removeLayerComp(compList, compName);
// create a new Layer Comp to store current visability state
var newcomp = compList.add(compName, “comp to store visibility of layers when viewing individual layer”, true,false);
return;
}

document.getElementById(“btnCrLView1”).addEventListener(“click”, function(){createLayerComp(“test”);} );

I know this doesn’t work because of the core.executeAsModelFunction for both the remove and add functions in the code. But not sure where to put it.

Bill

My other question is if there are two layer comps with the same same name what does getAllByName return, just the first one or an array of all with the same name?

getAllByName returns all LayerComp with the same name as an array. You can achieve this by referencing them by [0] after executing getAllByName if you need the first one.

I know this doesn’t work because of the core.executeAsModelFunction for both the remove and add functions in the code. But not sure where to put it.

Maybe executeAsModel can be nested, so it might work even if you use it for both.

However, the best place to place it would be the moment the user takes action to make changes to the document. In this case, that would be the moment the button is clicked.

Not sure if this will actually work, it should be something like this.

document.getElementById("btnCrLView1").addEventListener("click", async () => {
  try {
    await core.executeAsModal(async () => 
      {
        await createLayerComp("test") ; // Change createLayerComp to async function
      }, 
      
      {
        commandName: "Create Layer Comp"
      }
    ) ;
  } catch(e) {
    await app.showAlert(e.message) ;
  }
}) ;