elysiajs / eden

Fully type-safe Elysia client
MIT License
147 stars 37 forks source link

How do you extract blob from response? #108

Open micoloth opened 2 months ago

micoloth commented 2 months ago

Hello!

First of all, I love this library. Very nice.

I have probably just a simple question. I didn't find it in the Documentation. And I tried different syntaxes but never worked.

How do you extract a Blob from an Eden response?

I.e. if you have an endpoint returning an Image body:

          // In FETCH:
          const response = await fetch(`/readfile/${encodeURIComponent(path)}`); // TODO: This has the .blob(); that idk how to use in Eden. 
          if (response.ok) {
            const blob = await response.blob();
            setImage(blob);
          }
          // In EDEN:
          // const response = await server.readfile[encodeURIComponent(path)].get();
          // ??

For context, setImage is used like this in React

  const [image, setImage] = useState<Blob | null>(null);
  {image && <img src={URL.createObjectURL(image)} alt="Loaded from server" />}     
lnfel commented 1 month ago

By default Eden would try to parse the response body and put it to response.data. It is not hundred percent accurate, for some cases we can use onResponse in eden treaty config to intercept responses and parse it the way we want to.

https://elysiajs.com/eden/treaty/config.html#onresponse

In my case I am returning FormData from elysia endpoint, but Eden only parses the form fields using get. The field named image can contain one or more images so I intercept the response and unwrap the File/Blob using getAll:

export const treaty = treaty2<App>(this.domain.replace('http://', '').replace('https://', ''), {
  async onResponse(response) {
    const contentType = response.headers.get('Content-Type')
    if (contentType?.includes('multipart/form-data')) {
      const formData = await response.formData()
      if (formData.has('image')) {
        return formData.getAll('image')
      }
    }
  }
})

Usage in client is like this:

const treatyResponse = await apiTreaty.image.convert.post({
  image: formData.getAll('image') as unknown as File | FileList
}, {
  query: {
    format: format.value as typeof ImageFormatSchema.static
  }
})

console.log(treatyResponse.data)