redux-toolkit icon indicating copy to clipboard operation
redux-toolkit copied to clipboard

RTK incorrectly parses non-json response types.

Open ChuckJonas opened this issue 3 years ago • 4 comments

I have an open api spec that I've generated a RTK reducer for:

"responses": {
          "200": {
            "description": "The OK response containing generated HTML",
            "content": {
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },

The response is type is a string with content-type of text-html (yuck), but on successful API request, RTK Query fails with an error:

error:
  data: "<!--[if !IE]><!--> <html class=\"nonIE8\">  <!--<
  error: "SyntaxError: Unexpected token < in JSON at position 0"
  originalStatus: 200
  status: "PARSING_ERROR"

Is there someway to properly get RTK to treat data as just a string instead of trying to parse the result as JSON?

ChuckJonas avatar Jun 22 '22 19:06 ChuckJonas

You can use enhanceEndpoints to overwrite that query function to set a responseHandler of text.

https://redux-toolkit.js.org/rtk-query/api/fetchBaseQuery#parsing-a-response

phryneas avatar Jun 22 '22 19:06 phryneas

If I understand correctly, I'd have to implement that custom handler for every endpoint of my API. Is there a way I can globally handle that?

(context: My API always returns plain text instead of JSON)

alexandernst avatar Sep 23 '22 17:09 alexandernst

@alexandernst You can pass responseHandler as an option into your fetchBaseQuery({..,}) call

phryneas avatar Sep 23 '22 21:09 phryneas

@phryneas Indeed, I saw that after replying to this thread. Actually, I replied you here: https://github.com/reduxjs/redux-toolkit/pull/2363#issuecomment-1256544055

alexandernst avatar Sep 23 '22 21:09 alexandernst

An example of this using generated code with injectEndpoints and enhanceEndpoints separately.

api.generated.ts

const injectedRtkApi = api.injectEndpoints({
  endpoints: build => ({
    users: build.query<
      ApiResponse,
      ApiArg
    >({
      query: () => ({ 
         url: '/users',
         method: 'POST',
         body: queryArg.body,
       }), // endpoint with text response
    })
    ...

api.customized.ts

export const api = generatedAuthApi.enhanceEndpoints({
  endpoints: {
    users: {
      query: queryArg => ({
        url: '/users',
        method: 'POST',
        body: queryArg.body,
        responseHandler: (response: { text: () => any }) => response.text()
      })
    },
 }
})

Actually is there a way to just extend the query defined in the generated file?

maurovisintin avatar Oct 27 '22 10:10 maurovisintin