Skip to main content
Disposition_Dev
Legend
December 8, 2016
Answered

Check for the existence of an expected element

  • December 8, 2016
  • 3 replies
  • 2569 views

Hello again, scripters!

I'm looking for a solution to a problem that has plagued me for quite some time.. In order to make my scripts more robust and less prone to failure, i spend a lot of energy writing test conditions to make sure that an expected element actually exists in the document. Now, this element could be a groupItem or a textFrame or a layer.. Basically anything.

The syntax I wish i could use is this:

if(docRef.layers["someLayer"].exists)

     {//do something}

else

     {//do something else}

But unfortunately "exists" is not a property of layer/groupItem/textFrame etc.

A quick example, since this happens to be what I was working on when i decided to write this post. I like to put stuff into a file upon completion of a task so that at runtime, i can check to see whether said process has already been completed and then determine whether to proceed or not. Perhaps there are better methods, but i typically create specifically named sublayers to indicate a task has been completed. Unfortunately, however, the checks become quite convoluted in order to avoid runtime errors for "no such element".

How do you guys check that an important element exists so you can be sure to proceed appropriately? My method seems to always go back to try/catch blocks that can sometimes end up really ugly looking. I think I'm at the point of writing myself an abstract function that I can call whenever I need it, but i wanted to see how you guys handle similar issues before i invest the time into writing something potentially unnecessary.

Thanks in advance everyone. 😃

This topic has been closed for replies.
Correct answer CarlosCanto

do you use a similar kind of checking function? How do you handle these types of situations?


It depends, when targeting named objects that I KNOW will fail, I always use try/catch.

If I'm expecting objects returned from a function I may add a true/false property then use if (true) {}.

if I need lets say at least one document to proceed, I use if (docs.length>0) {}

3 replies

Disposition_Dev
Legend
December 13, 2016

So, i think I've worked out an easier way to determine what failed in a try block (or at least the first failure), at least in terms of whether an element exists.. (this won't work for actual tasks performed by the script).

//first declare the variables that will be defined in the try block

var something,

     somethingElse,

     lastThing;

try{

     var something = someValue;

     somethingElse = someOtherValue;

     lastThing = lastValue; //lets say 'lastValue' doesn't exist. so we head over to the catch

}catch(e){

     if(something == undefined){

          alert("something is undefined. someValue does not exist);

     }

     if(somethingElse == undefined){

          alert("somethingElse is undefined. someOtherValue does not exist);

     }

     if(lastThing == undefined){

          alert("lastThing is undefined. lastValue does not exist);

     }

}

This will at least show me the first instance of a missing element.

Inspiring
December 10, 2016

I have never write code like this, but that's the sequence if you want to ensure obj really exists: app > document > layer (optional) > group (optional)  > (path, textframe, etc.)

function isExists(obj, prop) {

    var valid;

    try {

        obj[prop];

        valid = true

    } catch (e) {

        valid = false

    }

    return valid

}

if (isExists(app, 'activeDocument')) {

    if (isExists(activeDocument.layers, 2)) {

        if (isExists(activeDocument.layers[2].groupItems, "nameOfGroup")) {

            alert('ok');

            // do some thing;

        } else {

            // do some thing;

        }

    } else {

        // do some thing;

    }

} else {

    // do some thing;

}

Disposition_Dev
Legend
December 8, 2016

::sigh::

Well as per usual, the very act of trying to explain my predicament helped shed some light. Thanks to all of you for being my rubber ducks.

I'll need to do some much more thorough testing on this to make sure it doesn't break down somewhere else (let me know if you can imagine a situation where it will fail). I'd love your thoughts on the below solution.. Should this have been a very "DUH" solution that i should have been using since day 1?

function exist(parent,child)

{

    var valid;

    try

    {

          var test = parent[child];

          valid = true;

    }

    catch(e)

    {

          valid = false;

    }

    return valid;

}

//then it would be implemented thus:

if(exist(myLayer.groupItems , "nameOfGroup"))

{

    //do something

}else

{

    //do something else

}

Disposition_Dev
Legend
December 8, 2016

Hmmm. No. That doesn't really work in such a simplistic form. It can still cause runtime errors in the exact same way because the arguments are evaluated before the function is executed. So if some parent doesn't exist, everything comes crashing down before the exist function even has a chance to test it.. Example:

doc has a single layer. The script will fail if you try to do something like:

if(exist(doc.layers[1].groupItems, "nameOfGroup"))

{//etc};

Because the index is out of bounds...

I had another thought which was to simply pass the parent as a string, but then i had issues with variables being undefined during the evaluation..?

Silly-V
Legend
December 8, 2016

For those kinds of checking functions, you'd at least have to know your parent container - if the parent container itself is prone to not existing, I suppose your function can be first used to check for it in it's parent and so on.