How to use joplin api `/resources/:id/file`?

Original demand: Feature request: pasting images/files directly · Issue #10 · rxliuli/joplin-vscode-plugin · GitHub
Are there any examples available? I want to try to paste the image through vscode and upload it to joplin automatically. Are there any nodejs examples available?

  static baseUrl(url: string, param?: object) {
    const query = stringify(
      {
        ...param,
        token: config.token,
      },
      {
        arrayFormat: 'comma',
      },
    )
    return `http://localhost:${config.port}${url}?${query}`
  }

  async fileByResourceId(id: string) {
    return (await axios.get(ApiUtil.baseUrl(`/resources/${id}/file`))).data
  }
    const res = await resourceApi.fileByResourceId(id)
    console.log(typeof res)
    const path = resolve(__dirname, '../resource/resourcesByFileId.png')
    writeFileSync(path, res)

image
image

@laurent

problem solved.

Well, the creation still failed. . . @laurent

Error: Request failed with status code 500

    const fd = new FormData()
    const path = resolve(__dirname, '../resource/resourcesByFileId.png')
    fd.append('props', JSON.stringify({ title: 'image' }))
    fd.append('data', createReadStream(path))
    const resp = await axios.post<ResourceGetRes>(
      ApiUtil.baseUrl('/resources'),
      fd,
      {
        headers: fd.getHeaders(),
      },
    )
    console.log(resp.data)

Does it give any error message beside code 500?

I assume the issue is that the request is not sent in multipart format but I can't be sure as I don't know this library.

The curl request would be:

curl -F 'data=@/path/to/file.jpg' -F 'props={"title":"my resource title"}' http://localhost:41184/resources

-F means you upload the file as if it was from a form on a web page.

I tested it

With curl it would be -F 'data=@/path/to/file.jpg' (see the "@")

What is @?

This is to make curl load the data from the given file. If you don't put "@" it assumes you want to post the string "/path/to/file.jpg" instead of the file content.

1 Like

I currently create a stackoverflow question: https://stackoverflow.com/questions/64129884/how-to-convert-the-following-curl-call-to-nodejs-axios

Confirmed, there are some problems with axios. . . I use fetch (node-fetch) to upload normally

Ok that's good to know. I'd be curious to know how to replicate the 500 error you got though, as the app should have provided a proper error message.

Here is an example of axios unit test, you can simply run it here to reproduce

  1. clone repo && git checkout dev && yarn install
  2. Start electron development client
  3. Modify config.token(test/util/setupTestEnv.ts)
  4. Remove the skip flag and run it
  5. Get this error

You should be able to reproduce it with axios anywhere

Thanks for the information, I'll give it a try.

I was able to replicate the issue but there's no easy way to improve the error code. Technically it should be error 4xx since the request was invalid but since for certain cases it's hard to tell if it's an internal error or user error, an error 5xx is returned.

In general when testing the API, if you get a 500 error, the best is to look at the response body, which should contain detailed info about the error. For example:

$ curl --data '{"title":"bla"}' http://localhost:27583/tags?token=TOKEN

{"title":"bla","id":"35f4e2b755444e35bf2c9b34fff88936","updated_time":1602237094307,"created_time":1602237094307,"user_updated_time":1602237094307,"user_created_time":1602237094307,"type_":5}

$ curl --data '{"title":"bla"}' http://localhost:27583/tags?token=TOKEN

{"error":"Internal Server Error: The tag "bla" already exists. Please choose a different name.: \n\nError: The tag "bla" already exists. Please choose a different name.\n at Function.save (/home/laurent/source/joplin/ElectronClient/lib/models/Tag.js:184:55)"}

Now, I filed a bug for axios. . .

Part of the issue, and I don't know if it's a problem with axios or Jest, is that when there's an error it just displays "failed with status code 500", but Joplin actually sends back detailed info about the error, which is not being displayed here. If it was it would be easy to tell if it's an error in the test, or Axios, or Joplin.

But fetch succeeded, so. . .