Amareis / another-rest-client

Simple pure TypeScript REST API client that makes your code lesser and more beautiful than without it.
MIT License
174 stars 16 forks source link

Support for blob (or any other) response type #12

Closed Fatal1stZ closed 6 years ago

Fatal1stZ commented 6 years ago

Nice rest client! But it only works with string response type, because of it's set by default. So, when we try to work with blob (e.g. trying to get pdf from server), the blob from response goes incorrenct because of wrong xhr.responseType.

To get the pdf get viewed correctly, i had to set responseType manually and handle it in success hook:

    rest
      .on( 'request', xhr => {
        xhr.responseType = 'blob'
      } )
      .on( 'success', xhr => {
        const blob = new Blob( [ xhr.response ], { type: 'application/pdf' } )
        FileSaver.saveAs( blob, `report.pdf` )
      } )
      .on( 'error', xhr => {
      } )
      [ REPORTS ]
      .get( report )

Would be nice to configure the xhr.responseType property and get the results from xhr.reponse, not from xhr.reposneText as it is now.

Amareis commented 6 years ago

Ok, i'll do that today at evening.

Amareis commented 6 years ago

@Fatal1stZ how library should installs responseType? Maybe user should set it in request event by himself?

Amareis commented 6 years ago

@Fatal1stZ check v0.4.0 image

Fatal1stZ commented 6 years ago

I checked your update, looks like it works. But. const result = await rest[ REPORTS ].get( report ).on( 'request', xhr => { xhr.responseType = 'blob' } ) It didn't work. It worked only like

rest.on( 'request', xhr => { xhr.responseType = 'blob' } )
const result = await rest[ REPORTS ].get( report )

Perhaps, it would be better to setup Response Type like an option as ContentType:

const result = await rest[ REPORTS ].get( query, {
contentType: 'application/pdf',
repsonseType: 'blob'
} )

What do you think?

Amareis commented 6 years ago

Oh, of course it didn't work -_- My code emits request before promise returns, so it's just a stupid error. I fix it now.

About options in get - this will breaks it API, because get can gets multiple objects to be encoded in query args. image

Amareis commented 6 years ago

Ok, i fixed this issue with once request event, check v0.4.1

Fatal1stZ commented 6 years ago

Yeah, it works now. Thank you.

About options - it should like an object in second argument, like you implemented ContentType setup:

const result = await rest[ REPORTS ].get( report, { contentType: 'application/pdf', responseType: 'blob' } )
const result = await rest[ COOKIES ].post( cookie, { contentType: 'application/json', responseType: 'text' } )

This could make the code cleaner.

Amareis commented 6 years ago

Yes, but you do not need to set the contentType in get - it's just pointless. I think, i can make this - if you passes objects in get, it's just query arguments. If you passes objects and string at end - string is responseType. If you pass only string - it's already encoded query args. And if you passes two strings - it's encoded args and responseType. In post, put and patch, if your passes string as second argument - it's contentType, but if you passes object in second arg, it's contentType and responseType. So, it's don't break API and make the trick, do you think?

Fatal1stZ commented 6 years ago

It makes, but also makes your api more messed. Isn't it cleaner to pass in second argument object with some xhr settings?

Fatal1stZ commented 6 years ago

Hi Amareis! What's up with responseType set in API, will you do anything about it?

Amareis commented 6 years ago

I don't want to rework existing API right now.