RicoSuter / NSwag

The Swagger/OpenAPI toolchain for .NET, ASP.NET Core and TypeScript.
http://NSwag.org
MIT License
6.75k stars 1.29k forks source link

TypeScript: Improve date time handling in clients #62

Closed RicoSuter closed 8 years ago

RicoSuter commented 8 years ago
  1. Support "\/Date(1198908717056)\/" by replacing all matches with new Date(...): http://weblogs.asp.net/bleroy/dates-and-json
  2. Support ISO date time format by converting string values to Date (only possible with TS classes): Must be fixed in NJsonSchema: https://github.com/NJsonSchema/NJsonSchema/issues/55
  3. Add optional reviver function to JSON.parse(text[, reviver]): https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse
var text = response.text();
var data = JSON.parse(text, this.reviver);

Date/time revivier function: http://stackoverflow.com/questions/1792865/how-to-use-json-parse-reviver-parameter-to-parse-date-string

The default reviver function should implement 1. from this list...

RicoSuter commented 8 years ago
  1. Support added: https://github.com/NSwag/NSwag/commit/c71f2ae9615c987be45c732f73c948a714028a73
  2. Still open
  3. Reviver added to Angular 2 tpl: https://github.com/NSwag/NSwag/commit/c71f2ae9615c987be45c732f73c948a714028a73, should it be added to other tpls too?
berhir commented 8 years ago

I have tested the new version and I get some TypeScript errors.

readonly properties are planned for TypeScript 2.0 but we still use 1.8.x. Is it really necessary to break backward compatibility?

And the following error:

var text = response.text().replace(/\/Date((-?\d*))\//, (a: string, b: string) => { return new Date(+b); });

Argument of type '(a: string, b: string) => Date' is not assignable to parameter of type '(substring: string, ...args: any[]) => string'.
  Type 'Date' is not assignable to type 'string'.   
RicoSuter commented 8 years ago

Oh no, I'll fix this ASAP. Readonly is already implemented for some months... maybe I should add an option to disable this... Where does your readonly properties come from? Do you have readonly attributes on the C# classes?

RicoSuter commented 8 years ago

Ok, fixed, I removed the replace part (because it is not really needed anymore)... only problem are the readonly props: Ill add an option to disable the generation of the readonly keyword

berhir commented 8 years ago

We have readonly attributes on our C# classes and Swashbuckle reflects this in the generated swagger.json. I have tried it again with NSwagStudio version 2.5.5940.40228 (06.04.2016 22:20:56) and there are no readonly attributes in the generated TypeScript interfaces.

RicoSuter commented 8 years ago

This is strange, readonly generation has been added one month ago: https://github.com/NJsonSchema/NJsonSchema/commit/0cf3a6368b1c89eb5b62543fcbd643419e1f43d9

I'll add an option to disable the generation of the keyword soon...

RicoSuter commented 8 years ago

Is the reviver function working for you?

berhir commented 8 years ago

Yes, it's working! Thanks!

RicoSuter commented 8 years ago

Ok that's fine... I will add the option to disable readonly keyword generation and the option to generate TypeScript classes instead of interfaces: This way the conversion from string to Date can be generated and will be correct on a per property basis...

RicoSuter commented 8 years ago

Ok, readonly is now a setting in v2.9

grovesNL commented 7 years ago

Reviver added to Angular 2 tpl: c71f2ae, should it be added to other tpls too?

That would be great. I may submit a PR for fetch if I have some time.

RicoSuter commented 7 years ago

Removed jsonParseReviver from ctor, use extension class to modify reviver: see https://github.com/NSwag/NSwag/wiki/SwaggerToTypeScriptClientGenerator#add-a-custom-jsonparse-reviver-function

admir86 commented 5 years ago

@RicoSuter what is the reason you removed the jsonParseReviver from ctor? Via DI it was easier to set a custom reviver. Or is there a way to create extension class for all my services without specifying each of them in the settings? We have a huge set of projects and all of them are using the same nswag.json and it would be difficult / time consuming to implement something that detect all Controller at the build time to inject the names via a variable to nswag.json.

Another way were, to add the possibility to generate the jsonParseReviver for each 200 status response. In the specific action of the service it would be possible to transform the date time by key (property) and not via regex. e.g.:

if (status === 200) {
  const reviver = (key: string, value: any) => {
    if(key === "birthday"){ //nswag knows birthday is of type date
      return new Date(value);
    }
  return value; 
  }; 
  return blobToText(responseBlob).pipe(_observableMergeMap(_responseText => {
    let result200: any = null;
    result200 = _responseText === "" ? null : <UserModel>JSON.parse(_responseText, reviver);
    return _observableOf(result200);
  }));
}

I think performance should be better, than check the value by a regex pattern in a global jsonParseReviver.