I am trying to teach myself some JXA
. So I have this simple piece of AppleScript
that I want to convert to JXA
:
tell application id "DNtp"
set theRecords to (search "name:__openai_api_key__")
set theRecord to first item of theRecords
set theContents to plain text of theRecord
end tell
The above code works and based on the information I have read I came up with the following JXA
code:
(() => {
const app = Application("DEVONthink");
const theRecords = app.search("__openai_api_key__")
const theRecord = theRecords[0]
const text = theRecord["plain text"]();
return text;
})()
When I run this the script it returns the error:
devon.js: execution error: Error: Error: Can't convert types. (-1700)
I can remove the error by changing line 5 to
const text = theRecord["plain text"];
which then makes the script return the value:
Application("DEVONthink").databases.byId(1).contents.byId(233034).plain text
What am I doing wrong?
You should work on your search queries as that really doesn’t say much. Search what for "__openai_api_key__"
? Tags? Content? Finder Comments?
Also, you have no validation there are any results at all nor if they’d have plain text.
Here I validated there are results to process but also filtered my search with search prefixes, establishing I was looking for tags
containing devontech and a document kind
.
Thanks for your reply. I noticed that you access the field as “plainText” instead of “plain text”.
I changed the code to:
(() => {
const app = Application("DEVONthink");
const theRecords = app.search("__openai_api_key__")
const theRecord = theRecords[0];
const text = theRecord["plainText"]();
return text;
})()
And now it works. I did not change the search criteria, although when I change the search line to:
const theRecords = app.search("name: __openai_api_key__")
it also works.
Is there a general rule that properties that you access with spaces, that I have to convert the field name to camel case?
Look at the scripting dictionary. The proper class and property names are in there.
And it’s better to be more specific in searches unless you really have no good idea where the search terms may occur.
Instead of accessing properties with array syntax, you could do
const txt = record.plainText()
Saves some typing.
Also, there’s no need to prefix variables with the
in JXA, unless you’re using a reserved word like if
.
You’ll find some examples of JXA scripts in the forum and others on Scripting with JXA | JavaScript for Automation (JXA)
The script suite of version 4 includes also several examples, both AppleScript and JXA to easily compare them.
Agreed. That was an omission.
My source of information is indeed the JavaScript for Automation.
There you can find this piece of code:
(() => {
const app = Application("Mail");
const account = app.accounts["boo"];
console.log(`${account.name()}`);
})()
The followed with this comment:
Alternatively, you can leave out the square brackets if the name does not contain special characters like spaces
So given that the dictionary specifies the property of record
is named plain text
, I used the square bracket approach given that the property does have a space.
I just double checked the dictionary and it turns out that I was looking at the AppleScript
dictionary and the JavaScript
dictionary does define it as plainText
.
Lesson learned. Thanks.
I know what you can find there, since I wrote that stuff 
But you should actually try to read it in context! The snippet you quoted was talking about access to array-valued properties. Which plainText
clearly is not.
Your code was not wrong, just a bit cumbersome. And the part about JavaScript vs AppleScript is mentioned too, in the section about the scripting dictionary.
Yes, I know. Just simply overlooked since I’m so used to look at the AppleScript
section.
BTW, my first version was more compact but I dumbed it down to figure out where my logic was wrong.
Thank you for your support.