I need some help to convert AppleScript to JXA

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 :winking_face_with_tongue:
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.