2

I have declared global variables at the top of the script, and I have initialised them.

I can set the do JavaScript to the variable emptyDue fine. But then as soon as I try to compare the result of the JavaScript to the serviceDate variable, I get

error "The variable emptyDue is not defined." number -2753 from "emptyDue"

Why can I assign emptyDue on one line, and then on the very next line, it suddenly forgets that it should exist?

global emptyDue, serviceDate
set emptyDue to ""
set serviceDate to "2021-11-30"

on isEmptyDue()
    
    tell application "Safari" to tell document 1
        
        set emptyDue to do JavaScript "document.getElementById('trgUseNext').click();
 document.getElementById('trgUseNext').value; --gets the date value from a webpage."
        
        if emptyDue < serviceDate then
            display dialog "TRUE"
        else
            display dialog "FALSE"
        end if
        
    end tell
    
end isEmptyDue

isEmptyDue()
log emptyDue
7
  • So what do you think happens when that document element doesn't exist? Commented Nov 4, 2021 at 16:44
  • codeblog.jonskeet.uk/2010/08/29/writing-the-perfect-question "There’s no need to include greetings and sign-offs such as “Hi everyone!” and “Thanks – hope to get an answer soon” in the question. These will often be edited out by other users, as they’re basically a distraction. Greetings at the start of a question are particularly useless as they can take up valuable space in the snippet displayed in the question list." Commented Nov 4, 2021 at 16:44
  • @red_menace I don't understand the question, sorry. Which document element are you referring to? Commented Nov 4, 2021 at 16:46
  • 1
    @epascarello Hi there! Thanks for your comment, very much appreciated. It really helped me with my problem. Have a great day! Commented Nov 4, 2021 at 16:47
  • That would be the document.getElementById('trgUseNext') you are trying to use. Commented Nov 4, 2021 at 16:48

2 Answers 2

2

There is a known flaw in AppleScript’s design: it is possible for a command to return no value. If you then bind the result of that command to a variable, it effectively makes that variable undefined.

You can avoid that -2753 error by making sure your command always returns a value, even if that value is just an empty string.

Sign up to request clarification or add additional context in comments.

1 Comment

Great observation. Just to help others who are having the same problem: a very easy way to ensure that you always return a value, is to wrap your js command in a try block.
1

This is a known AppleScript bug, as pointed out by user foo's answer to this question. Here is a little code snippet that might help others work around the same problem:

on tryJavaScript(js)
    set outVal to ""
    set tried to 0
    set js to "try{" & js & "}catch{null};"
    
    tell application "Safari"
        
        tell current tab of first window to repeat
            set outVal to do JavaScript js
            try
                set working_around_error_2753 to outVal
            on error number -2753
                set outVal to "not found"
            end try

            if outVal is not "null" then exit repeat
            delay 0.1
            set tried to tried + 1
            if (tried > 5) then return "unrecoverable"
        end repeat
        
    end tell
    return outVal
end tryJavaScript

You would call this handler with the following syntax:

set emptyDue to tryJavaScript("document.getElementById('trgUseNext').click();
 document.getElementById('trgUseNext').value;")

Or, if you want an example that will work on the HTML of a StackOverflow page, try:

set myOutput to tryJavaScript("document.getElementById('footer').innerText;")

This won't guarantee that your JavaScript will work, but at least it will give you a more meaningful error message to work with.

2 Comments

The line if outVal is not "null" then exit repeat can't be right? In case you get a -2753, outVal is set to "not found" and then it is not null and the loop exits, without trying 5 times.
It is right, because we need to allow for AppleScript not hearing back from the JavaScript in time. We want to exit the loop if we get either a valid result, or an error. If the result is "null", we may simply not have waited long enough. You could avoid the need for a loop by simply having a much longer timer, but this method exits as soon as we can.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.