Setting PDF data with JXA does not work

I’m trying to write a JXA script which sets the data of a PDF record - unfortunately neither createRecordWith({name:"Test", data:data}) nor r.data = data works.

app = Application("DEVONthink 3");
records = app.selectedRecords();
records.forEach(r => {
	// Create a new PDF record with the data from the current record
	app.resultRecord = app.createRecordWith({name:"Test", type:"PDF document", data:r.data()});
});

When I use this on a selected PDF record Script Editor gives ‘Error -50: Parameter error’ and pops up an “Invalid argument data” error. When trying to set r.data = data for a record r with other scripts no data is set at all. This method does work in AppleScript.

Any clues on how this should work? Or is the data property broken in JXA?

Side note: I noticed that on the createRecordWith function in the Dictionary it incorrectly mentions creation and modification as arguments, which are wrong as they should be creationDate and modificationDate so maybe something is going wrong with the AS-JXA translation here (as well)?

1 Like

Just a typo in the description, thanks.

You’re welcome! Wish that data question could be solved as easily as well :slight_smile:

@cgrunenberg would have to comment on that. But I seem to remember that data returned some hex encoded data, eg for images. Never figured out how to get actual data from it.

That’s a weird conversion (and IMHO a bug) applied by JXA, AppleScript doesn’t do that.

Just to clarify: if, for example, I have a jpeg image in DT, data would be the binary content of this image in AppleScript? And in JS I’d get some kind of hex ascii which should be equivalent to the binary data?
I’m asking because then it just might be possible to en/decode the stuff in JS. Perhaps.

Exactly.

DEVONthink will handle this soon, this works now over here:

app = Application("DEVONthink 3");
records = app.selectedRecords();
records.forEach(r => {
	resultRecord1 = app.createRecordWith({name:"Test", type:"PDF document", data:r.data()});
	resultRecord2 = app.createRecordWith({name:"Test", type:"PDF document"});
	resultRecord2.data = r.data();
});

@cgrunenberg that’s what I’m trying here, but gives me a Parameter error as described above. Do you mean you have this working in your internal builds for the next release?

Yes.

1 Like

Great. Another one added to my things-to-look-forward to in the next release.

Just curious if you’re willing to collaborate, why wasn’t it working? I always understood AppleScript → JavaScript was an automatic translation so there wasn’t much to do if it wasn’t working?

I almost when the route of using @houthakker’s script to evaluate AppleScript via Obj-C in a JSContext. Inception! :slight_smile:

It is but unfortunately it has a bunch of its on flaws & bugs (and doesn’t get much love from Apple). In the meantime you could of course use AppleScript which works flawlessly :rofl:

4 Likes

Will data behave like that across all types of records, eg images?

Of course.

:+1:

Criss, just to verify - this also means that something like resultRecord.data = window.pdf() ) (which is my original use case) should work now, right?

It should work, please post the complete script and I’ll try it.

A boiled down version of my script:

const app = Application("DEVONthink 3");
r = app.createRecordWith({name: "DEVONtechnologies", URL:"https://www.devontechnologies.com", type:"bookmark");
let rWindow = app.openWindowFor({record: r});	
app.createRecordWith({name: r.name(), URL:r.url(), type:"PDF document", data: rWindow.pdf()});

Thanks for testing Criss!

Basically working, the PDF is just a white page as the web page wasn’t loaded right after opening the window.

Not loaded yet, I guess? Like: it would be nice if we had a callback that fires when the page is loaded?