The TypeScript Fetch client generator with promises seems to cause some strange behaviour compared to for example the Angular2 client generator with the same options when handling 204 responses from a delete endpoint with the option WrapResponses = enabled.
For example, the Fetch client generator generates the following code to handle the 204 response:
if (status === 204) {
return response.text().then((_responseText) => {
return;
});
}
Which will throw an error because the generated ProcessDelete method expects a return of type Promise<SwaggerResponse<void>>.
While the Angular2 generator generates the following code, with the same endpoint and the same generator settings:
if (status === 204) {
const _responseText = response.text();
return Observable.of<SwaggerResponse<void>>(<any>null);
}
Which is a valid return for the generated ProcessDelete method.
These are the settings i am using for respectively the fetch and angular generator:
new SwaggerToTypeScriptClientGeneratorSettings
{
ClassName = "{controller}Client",
PromiseType = PromiseType.Promise,
BaseUrlTokenName = "API_BASE_URL",
ImportRequiredTypes = true,
Template = TypeScriptTemplate.Fetch,
WrapResponses = true,
TypeScriptGeneratorSettings =
{
MarkOptionalProperties = true,
TypeScriptVersion = 2.0m,
}
};
new SwaggerToTypeScriptClientGeneratorSettings
{
ClassName = "{controller}Client",
Template = TypeScriptTemplate.Angular,
GenerateOptionalParameters = true,
WrapResponses = true,
TypeScriptGeneratorSettings =
{
TypeScriptVersion = 2.0m,
}
};
Am i doing/understanding something wrong or is this a bug in the fetch client generator template?
If you need any more information please let me know.
Thanks in advance
This is probably a bug - I dont use WrapResponses in any of my projects, so this is not as well tested as the other options... I even think that the angular code is wrong - it should always return a SwaggerResponse and never null...
Thanks for the quick response!
If i understand correctly, the following code https://github.com/RSuter/NSwag/blob/21a5f65f44f8136e91df2ba01f1d4ae71781572b/src/NSwag.CodeGeneration.TypeScript/Templates/Client.ProcessResponse.HandleStatusCode.liquid#L57-L64
would need to be changed to also have an option for isFetchOrAurelia? If so, i will see if i can fix this
Yes but only in the case of WrapResponses... if the setting is off then it is correct...
I think your code selection should be replaced by
{% elseif response.IsSuccess -%}
{% if operation.WrapResponse -%}
{% if IsAngular -%}
return Observable.of<{{ operation.ResultType }}>(<any>null);
{% elseif IsAngularJS -%}
return this.q.resolve<{{ operation.ResultType }}>(<any>null);
{% else -%}
return{% if operation.HasResultType %} null{% endif %};
{% endif -%}
{% else -%}
{% if IsAngular -%}
return Observable.of<{{ operation.ResultType }}>(<any>null);
{% elseif IsAngularJS -%}
return this.q.resolve<{{ operation.ResultType }}>(<any>null);
{% else -%}
return{% if operation.HasResultType %} null{% endif %};
{% endif -%}
{% endif -%}
{% else -%}
where the first part (if operation.WrapResponse) must be fixed
I think this could work:
{% elseif response.IsSuccess -%}
{% if operation.WrapResponse -%}
{% if IsAngular -%}
return Observable.of<{{ operation.ResultType }}>(new {{ operation.ResponseClass }}(status, _headers, <any>null));
{% elseif IsAngularJS -%}
return this.q.resolve<{{ operation.ResultType }}>(new {{ operation.ResponseClass }}(status, _headers, <any>null));
{% else -%}
return new {{ operation.ResponseClass }}(status, _headers, <any>null);
{% endif -%}
{% else -%}
{% if IsAngular -%}
return Observable.of<{{ operation.ResultType }}>(<any>null);
{% elseif IsAngularJS -%}
return this.q.resolve<{{ operation.ResultType }}>(<any>null);
{% else -%}
return{% if operation.HasResultType %} null{% endif %};
{% endif -%}
{% endif -%}
{% else -%}
You can test this by overriding the template: https://github.com/RSuter/NSwag/wiki/Templates
Then report back here or create a PR..
Thank you, the provided code seems to work without problems in my project as far as i can see
@quails4Eva @ml-dev @BringerOD
Can you verify?
I think WrapResponse should always return a response object and never null, what do you think?
@RSuter
I would agree that WrapResponse should always return a response object and never null.
I haven't been working on the project that uses this recently, but I agree that it shouldn't return null.
Please retest with latest CI artifacts
Most helpful comment
This is probably a bug - I dont use WrapResponses in any of my projects, so this is not as well tested as the other options... I even think that the angular code is wrong - it should always return a SwaggerResponse and never null...