I am playing with some ideas to expand my use of JXA for scripting.
The very brief script below is intended simply to explore how I can assign names and other metadata to a file in DT3.
I was hoping this example would reassign the filename of the first item in the list of selected items. Script Editor gives me “Error -2700 Script Error.” Keyboard Maestro give the error that I am assigning to the incorrect type.
@winter has already explained the const issue. That’s why I always use an anonymous self-executing function to run my JS code
Also, your assignment will not change the name of the first record to “test”. Here’s what happens:
app.selectedRecords gets an array of Object Specifiers, namely the selected records
app.selectedRecords.name gets an array of Object Specifiers, namely the names of the selected records
app.selectedRecords.name() does a get on these names, which results in an array of Strings.
Now you assign a new value to the first element of this array, which works fine. But it will not change the name of the first record because the first element of the array of Strings will not have any connection to the records. It does not contain references (or Object Specifiers), but values. So to say.
What would work is app.selectedRecords.name = "test"
because there name is an Object Specifier, and assigning to it is equivalent to a set operation.
The problem here is that JXA uses confusing syntax: () gets a value, and assignment to the Object Specifiers sets its value. If they’d used set and get, it would be clearer.
Attempt at an explanation: app.selectedRecords.customMetadata is an Object Specifier, but app.selectedRecords.customMetadata['md…'] is not, but only a string (or number or whatever). JXA is probably getting confused because everything kind of “looks” like an Object Specifier, and then it tries to call its set method, which doesn’t work. Sounds a bit far-fetched, perhaps.
If you run the script in Script Editor, you’ll immediately spot these things (not because the program is so good, but:) You can have it display the Apple Events it sends and receives, and then you’ll see that selectedrecords is passed as null:
If it were a good program, it would immediately tell you that app doesn’t have a property selectedrecords when “compiling”. But, helas … it’s not even compiling anything but just running a basic syntax check.
AFAIK: Not. The main issue here is (in my opinion) that Apple does not provide for introspection of its objects. They are just black boxes. While you can step through a JXA script in Safari (add debugger at the point where you want Safari to take over), it is of very little help for anything related to application scripting (for the reason mentioned before).
You’d see the same problem with WebStorm (which would not be able to run your scripts because it doesn’t know how to call into OSA!). So, I use plain old config.log to “debug” my code.
Only for the JS code outside of application scripting, since even Safari does not provide any introspection for application objects, like DT records. So, it’s really quite limited. Running the script in Script Editor can sometimes provide more insight, since you can follow the Apple events and responses there.