NSwag icon indicating copy to clipboard operation
NSwag copied to clipboard

CodeGen: Typescript + Axios + transformRequest

Open it-xtech-dev opened this issue 2 years ago • 5 comments

First of all, thanks to all of the contributors - this is great piece of software!

I'm having issues generated Typescript client with Axios and using option TypeStyle: Interface (for Class option works fine).

My axois instance is configured to parse response with custom reviver:

// preconfigure axios http client custom response parsing function that will parse dates as objects rather than strings
const ax = axios.create({
  transformResponse: [function (data: string): unknown {
    // Automatically convert serialized dates to javascript objects
    if (data) return JSON.parse(data, dateReviver)
  }],
  //...
});

In result when going down to generated client library, response becomes object instead of string (sample request processing):

protected processTools_GetFile(
    response: AxiosResponse
  ): Promise<FileResponse> {
  //...
}

And later processing fails on:

    } else if (status === 200) {
      const _responseText = response.data;
      let result200: any = null;
      let resultData200 = _responseText;
      // here the code fails because resultData200 is not json string but already parsed object
      result200 = JSON.parse(resultData200);

I have dug into template https://github.com/RicoSuter/NSwag/blob/cfaaec0bae7d0a83b2d7cb093dc96b57c5ebd499/src/NSwag.CodeGeneration.TypeScript/Templates/Client.ProcessResponse.HandleStatusCode.liquid#L47 and I see that JSON.parse is conditional based on IsPlainText property. Somehow in this case request is assumed to be plain text.

I have search the project IsPlainText and found it at https://github.com/RicoSuter/NSwag/blob/cfaaec0bae7d0a83b2d7cb093dc96b57c5ebd499/src/NSwag.CodeGeneration/Models/ResponseModelBase.cs#L88 My understanding ends here because don't know how it influences typescript generation (as pointed earlier IsPlainText seems to be evaluated to false).

Is it possible to handle this case? Possibly by changing template to:

let contentType = _headers['content-type'];
if (contentType.includes('application/json')) {
   result{{ response.StatusCode }} = resultData{{ response.StatusCode }};
} else {
   result{{ response.StatusCode }} = {% unless response.IsPlainText %}JSON.parse({% endunless %}resultData{{ response.StatusCode }}{% unless response.IsPlainText %}){% endunless %};
}

it-xtech-dev avatar Aug 19 '22 09:08 it-xtech-dev

Have you fixed the template for your personal uses? if yes can you send it to me

Omega-me avatar Sep 05 '22 12:09 Omega-me

Well finally I have done some extensive changes. I have extracted Axios related templates to separate files and have handled both class and interface settings. It would be nice to include sort of this into NSWAG core templates or maybe as a FLAVOR of Axios - as an alternative to default Axios template.

Here are my templates, feel free to use them. I have also included my use case base class implementation. Templates.zip

it-xtech-dev avatar Sep 11 '22 18:09 it-xtech-dev

same problem

vipwan avatar Sep 25 '22 13:09 vipwan

Here is a workaround: https://github.com/RicoSuter/NSwag/issues/3294

feelgood-interface avatar Dec 03 '22 00:12 feelgood-interface

I have the same issue. This issue was for 2 years ago. Is there any hope of having it fixed soon?

trudyhood avatar Apr 26 '24 18:04 trudyhood