# Single Javascript Function Question

**URL:** <https://forums.creativeclouddeveloper.com/t/single-javascript-function-question/4737>\
**Category:** UXP Plugin API\
**Created:** [May 30, 2022, 8:55am UTC](https://forums.creativeclouddeveloper.com/t/single-javascript-function-question/4737 "2022-05-30T08:55:08Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![IanBarber](https://avatars.discourse-cdn.com/v4/letter/i/94ad74/32.png) [@IanBarber](https://forums.creativeclouddeveloper.com/u/IanBarber)\
**Post date:** [May 30, 2022, 8:55am UTC](https://forums.creativeclouddeveloper.com/t/single-javascript-function-question/4737/1 "2022-05-30T08:55:08Z")

</div>

I asked a similar question to this which gave what appeared to be great answers but I don’t think I asked the initial question properly so I will try again 🙂

I am using Vanilla Javascript, no React, no web pack just plain simple Javascript with one index.js file.

I am also using API version 2 and Manifest 5

**Use Case** :  
I have 12 buttons on my plugin and each time one is pressed, I want to see if the active selected layer name = Paint Here

Through reading, I have managed to make a Loop which loops all layers and returns the layer name of the selected layer.

**Question:**  
Rather than having to write this loop out for each of the 12 buttons, is it possible to wrap the loop in a single function and then call that function from each of the 12 buttons.

I have tried the following but It always returns undefined

```auto
function checkName(y){
	
  const name = app.activeDocument.layers;

  // loop through all layers looking to see if the selected layer 
  //name includes Paint Here
	
  Array.from(name).forEach(function (x) {

	  if (x.selected == true) {
         
         if (x.name.includes(y)) {			
          return "yes"          
          }
       }
   
   });
}

//Call the function
console.log(checkName("Paint Here"));

```

---

<div class="post-metadata">

**Author:** ![simonhenke](https://sea1.discourse-cdn.com/flex015/user_avatar/forums.creativeclouddeveloper.com/simonhenke/32/957_2.png) [@simonhenke](https://forums.creativeclouddeveloper.com/u/simonhenke)\
**Post date:** [May 30, 2022, 9:48am UTC](https://forums.creativeclouddeveloper.com/t/single-javascript-function-question/4737/2 "2022-05-30T09:48:21Z")

</div>

Code works fine for me. If it returns undefined for you it’s due to one of the two reasons:

- the layer you try to find isn’t selected
- the name doesn’t match (string.includes is case sensitive)

Besides that, the code is kind of inefficient. You’re only interested in selected layers, so there’s no need to loop all (toplevel) layers. Also, you can call `forEach()` on the proxy directly and don’t need to wrap it in `Array.from`. Lastly, your expected result is some kind of affirmation / negation. Instead of returning a string (`"yes"`) or `undefined`, wouldn’t it be more plausible to have a `boolean` return type?

Besides that, your variable names are a bit misleading or hard to understand. `name` is effectively `layers` and the `y` parameter could be `name` or `searchedName`.

With all that applied, you could have it as a one-liner:

`const layerExists = (name) => app.activeDocument.activeLayers.some(layer => layer.name.includes(name))`

Explanation: `Array.some()` is like forEach but it checks against the condition and returns `true`/`false`, when at least one element is found. It also stops the loop then and skips all the rest.

You can then work with it like:

```auto
if(layerExists("Paint here")) {
  // do stuff
}

```

Might be worth mentioning also that your current string check is quite broad since you use `string.includes`. Something like `"Awesome Layer Paint here please"` would also match the condition, also it’s probably unlikely someone has a layer with such a name. A more strict check for equality would be:

`const layerExists = (name) => app.activeDocument.activeLayers.some(layer => layer.name === name)`

---

<div class="post-metadata">

**Author:** ![simonhenke](https://sea1.discourse-cdn.com/flex015/user_avatar/forums.creativeclouddeveloper.com/simonhenke/32/957_2.png) [@simonhenke](https://forums.creativeclouddeveloper.com/u/simonhenke)\
**Post date:** [May 30, 2022, 10:00am UTC](https://forums.creativeclouddeveloper.com/t/single-javascript-function-question/4737/3 "2022-05-30T10:00:00Z")

</div>

> [@IanBarber](#):
>
> **Question:**  
> Rather than having to write this loop out for each of the 12 buttons, is it possible to wrap the loop in a single function and then call that function from each of the 12 buttons.

To answer your original question: Yes, you can of course reuse a function you declared once in multiple button click handlers.

Btw, if you want to do some operations on that “Paint here” layer further down in your script, you might also want to check if only one layer is selected. Otherwise it might break if the user has multiple selected layers.

---

<div class="post-metadata">

**Author:** ![IanBarber](https://avatars.discourse-cdn.com/v4/letter/i/94ad74/32.png) [@IanBarber](https://forums.creativeclouddeveloper.com/u/IanBarber)\
**Post date:** [May 30, 2022, 10:54am UTC](https://forums.creativeclouddeveloper.com/t/single-javascript-function-question/4737/4 "2022-05-30T10:54:39Z")

</div>

@simonhenke Thanks for the explanation and examples.

Using your cleaner version, in the button click event, I now have

```auto
const layerExists = (name) => app.activeDocument.activeLayers.some(layer => layer.name === name)

    if (layerExists("paint here")) {
      console.log("Layer is there and selected");
    }

```

Question  
As an experienced coder, would you simply write the above in each button click event now its a 1 liner or would you create a global function and call that function from each button click ?

Also…

```auto
if (layerExists("paint here")){
}

```

Am I correct in thinking that the layer name has to be exact of what we are looking for and is also case sensitive ?

---

<div class="post-metadata">

**Author:** ![simonhenke](https://sea1.discourse-cdn.com/flex015/user_avatar/forums.creativeclouddeveloper.com/simonhenke/32/957_2.png) [@simonhenke](https://forums.creativeclouddeveloper.com/u/simonhenke)\
**Post date:** [May 30, 2022, 11:03am UTC](https://forums.creativeclouddeveloper.com/t/single-javascript-function-question/4737/5 "2022-05-30T11:03:56Z")

</div>

> [@IanBarber](#):
>
> As an experienced coder, would you simply write the above in each button click event now its a 1 liner or would you create a global function and call that function from each button click ?

Performance-wise it doesn’t really matter, but the point of outsourcing code in reusable functions is to write less code in other places, so I’d keep it outisde.

> [@IanBarber](#):
>
> Am I correct in thinking that the layer name has to be exact of what we are looking for and is also case sensitive ?

As mentioned, `string.includes` just checks if the match-string is anywhere inside the other string, not equality.

---

<div class="post-metadata">

**Author:** ![Karmalakas](https://sea1.discourse-cdn.com/flex015/user_avatar/forums.creativeclouddeveloper.com/karmalakas/32/1048_2.png) [@Karmalakas](https://forums.creativeclouddeveloper.com/u/Karmalakas)\
**Post date:** [May 30, 2022, 11:16am UTC](https://forums.creativeclouddeveloper.com/t/single-javascript-function-question/4737/6 "2022-05-30T11:16:40Z")

</div>

> [@simonhenke](#):
>
> As mentioned, `string.includes` just checks if the match-string is anywhere inside the other string, not equality.

I see Ian changed code to use the suggested `layer.name === name`, so yes, it’s exact and case sensitive

---

<div class="post-metadata">

**Author:** ![simonhenke](https://sea1.discourse-cdn.com/flex015/user_avatar/forums.creativeclouddeveloper.com/simonhenke/32/957_2.png) [@simonhenke](https://forums.creativeclouddeveloper.com/u/simonhenke)\
**Post date:** [May 30, 2022, 11:48am UTC](https://forums.creativeclouddeveloper.com/t/single-javascript-function-question/4737/7 "2022-05-30T11:48:19Z")

</div>

Oops, should had scrolled to the right in the code window 😅

---

<div class="post-metadata">

**Author:** ![IanBarber](https://avatars.discourse-cdn.com/v4/letter/i/94ad74/32.png) [@IanBarber](https://forums.creativeclouddeveloper.com/u/IanBarber)\
**Post date:** [May 30, 2022, 12:03pm UTC](https://forums.creativeclouddeveloper.com/t/single-javascript-function-question/4737/8 "2022-05-30T12:03:34Z")

</div>

All suggested code now working in an outside function.  
Having stepped through the code in the debugger I now feel as I have a better understanding how it is working.

The Array.some() was new to me and I will need to study this in more detail to get a better understanding of it.

many thanks for your help. I’m sure there will be others who will find it useful even though it may have been a simple question to some 🙂
