Nswag: TypeScript Fetch client generator error with WrapResponses enabled

Created on 10 Nov 2017  路  12Comments  路  Source: RicoSuter/NSwag

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

bug

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...

All 12 comments

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

Was this page helpful?
0 / 5 - 0 ratings