Swagger-codegen: [typescript-angular] error TS1345: An expression of type 'void' cannot be tested for truthiness

Created on 22 Oct 2018  路  25Comments  路  Source: swagger-api/swagger-codegen

Description

The generated typescript client fails in angular 7 build when there seems to be any sort of file field.

Typescript version

"typescript": "^3.1.3"

Swagger-codegen version

The latest online version

Swagger declaration file content or url
parameters:
        - name: attachment1
          type: file
          in: formData
          required: false

Produces:

if (attachment1 !== undefined) {
            formParams = formParams.append('attachment1', <any>attachment1) || formParams;
}

The definition of append tracks down to

let formParams: { append(param: string, value: any): void; };

screenshot 2018-10-22 at 2 13 46 pm

Steps to reproduce

Generate a new client with angular-typescript selected.

Most helpful comment

I would love to see a fix too !

All 25 comments

Same problem in our environment, after updating angular from v6 to v7 it is not possible to compile the genereated swagger services with the same error as seen above.
tried swagger-codegen-cli 2.4.0-SNAPSHOT and 3.0.2

Also happens with

import { Observable } from 'rxjs/Observable'

Which has to be :

import { Observable } from 'rxjs'

As a workaround you can use some bash after generating the code

sed -i 's/rxjs\/Observable/rxjs/' ./src/app/swagger/api/api.service.ts 
sed -i 's/formParams = formParams/formParams/' ./src/app/swagger/api/api.service.ts 
sed -i 's/ || formParams//' ./src/app/swagger/api/api.service.ts 

@Dviejopomata yeah this has been the case after updating the rxjs version to 6.0.0

@Dviejopomata , this actually has been implemented, you just need to pass the ngversion parameter while generating. The online generator is generating for angular 4.3 as a default.

@Dviejopomata , this actually has been implemented, you just need to pass the ngversion parameter while generating. The online generator is generating for angular 4.3 as a default.

do you have any pointers to what to set it? i tried with --additional-properties ngVersion=6.0.0 but that didn't seem to do anything.

@awalland Make sure you are using v3.0.0 at least, i had to change from v2.3.1 to v3.0.0 and it worked fine:

Since i'm using docker this is what my command looks like:

docker run --rm -v ${PWD}/src/app/swagger:/local swaggerapi/swagger-codegen-cli:unstable generate -i http://192.168.1.47:5070/swagger/v1/swagger.json -l typescript-angular -o /local --additional-properties ngVersion=6.0.0

I'm facing same problem, after I updating angular from v5 to v7. I used all version of swagger cli jars. I used following command to generate swagger code

java -jar ./swagger-codegen-cli-3.0.0-20180710.190537-87.jar generate -i http:///swagger/v1/swagger.json -l typescript-angular -o ./local --additional-properties ngVersion=7.0.0

With swagger-codegen-cli-3.0.3.jar I get invalid petApi.service.ts

petApi.service.ts(364,1): error TS1005: '}' expected.

Used command is
java -jar ./swagger-codegen-cli-3.0.3.jar generate -i petstore.yaml -l typescript-angular -o ./local --additional-prop erties ngVersion=7.0.0

Same if I use ngVersion 7.1.0

Also all codegen-cli (jars) are generating invalid typescript 3 code. Errors are related to rxjs Imports and An expression of type 'void' cannot be tested for truthiness

Problematic code is

    let formParams: { append(param: string, value: any): void; };
    let useForm = false;
    let convertFormParamsToString = false;
    if (useForm) {
        formParams = new FormData();
    } else {
        formParams = new HttpParams({encoder: new CustomHttpUrlEncodingCodec()});
    }
    if (name !== undefined) {
        formParams = formParams.append('name', <any>name) || formParams;
    }
    if (status !== undefined) {
        formParams = formParams.append('status', <any>status) || formParams;
    }

useForm boolean is basically hardcoded and FormData constructor is never used.
formParams should be of this type and formParams=new FormData() line removed (i thinlk):
let formParams: { append(param: string, value: any): HttpParams; };

Proposed fix: change the line

let formParams: { append(param: string, value: any): void; };

to

let formParams: { append(param: string, value: any): void | HttpParams; };

in the template file api.service.mustache

Is there any update on this issue (or the proposed PRs)?

@plathub This fix does not work because it is not only a typing issue, formParams.append could really return nothing or a new HttpParams with appended value.

I have resorted to running my own sanitise-swagger.sh after each generation

find ./src/swagger/api/*.service.ts -type f -exec sed -i '' -e 's/rxjs\//rxjs/' {} \;
find ./src/swagger/api/*.service.ts -type f -exec sed -i '' -e 's/formParams = formParams/formParams/' {} \;
find ./src/swagger/api/*.service.ts -type f -exec sed -i '' -e 's/ || formParams//' {} \;

This does the corrections on all files under /src/swagger which is where i keep my generated client.

@emmanuelgautier Can we not have a builder wraps around FormData that supports the same append signature ? Something similar to the below.

# builder.ts, new file
export interface FormBuilder {
  append(param: string, value: any): FormBuilder;
}

export class FormDataBuilder<T extends { append(param: string, value: any): void; }> implements FormBuilder {

  append(param: string, value: any): FormDataBuilder<T> {
    this.append(param, value);
    return this;
  }
}

# generated service
let formParams: FormBuilder;
if (useForm) {
    formParams = new FormDataBuilder<FormData>();
} else {
    formParams = new HttpParams({encoder: new CustomHttpUrlEncodingCodec()});
}

@sohoffice Creating a class just for one use case seem a bit over engineered IMHO. I prefer a simple function.

This MR fix the issue with the same method : https://github.com/swagger-api/swagger-codegen/pull/9012

@emmanuelgautier #9012 seems to be failing on angular v4, is there anything I can do to get it merged ?

I haven't found a valid workaround amongst the comments above... This problem appears also with _openapi-generator_ every time an endpoint function has to use FormData or HttpParam. My solution was to define differently the formData variable so it can return void or something like a new HttpParam:

        // HERE: if we use HttpParams the append function returns a new HttpParams object
        // instead if we use FormData the append function will not return anything
        let formParams: { append(param: string, value: any): void | HttpParams; };
        let useForm = false;
        let convertFormParamsToString = false;
        if (useForm) {
            formParams = new FormData();
        } else {
            formParams = new HttpParams({ encoder: new CustomHttpUrlEncodingCodec() });
        }

        if (newPassword !== undefined) {
            // here there is no more the syntax error
            formParams = formParams.append('newPassword', <any>newPassword) || formParams;
        }
        // here nothing changes
        return this.httpClient.post<any>(`${this.basePath}/accounts/reset-password`,
            convertFormParamsToString ? formParams.toString() : formParams,
            {
                withCredentials: this.configuration.withCredentials,
                headers: headers,
                observe: observe,
                reportProgress: reportProgress
            }
        );

By using this everytime we use FormData/HttpParams the HTTP requests result valid.

Still valid for v3.0.11. Is this gonna be resolved any soon?

hi @Hobart2967 , just assign it to myself, sadly i cant guarantee solve it soon, but once i have a chance i'll work on it

Just like @itsTeknas I have used a script (powershell) to solve this for the time being

java -jar .\swagger-codegen-cli-2.4.1.jar generate -i http://localhost:5100/swagger/v1/swagger.json -l typescript-angular -o ../src/api

$file = '..\src\api\api\thexyz.service.ts'
$find = 'let formParams: { append(param: string, value: any): void; };'
$replace = 'let formParams: { append(param: string, value: any): void | HttpParams; };'

(Get-Content $file).replace($find, $replace) | Set-Content $file

any news on this?

I would love to see a fix too !

As a temporary fix I used @itsTeknas solution on windows MinGw with a small dummy script launched on start up.
```var runCommand = require('child_process').execSync; //chose any name

var gen = 'java -jar src/swagger/swagger-codegen-cli-2.4.13.jar generate -i src/swagger/swagger-spec.yml -l typescript-angular -o src/app/generated';
var rxFix = 'sed -i 's/rxjs\/Observable/rxjs/' ./src/app/generated/api/.service.ts';
var frmFix = 'sed -i "s/ || formParams//" ./src/app/generated/api/
.service.ts';
var frmFix2 = 'sed -i 's/formParams = formParams/formParams/' ./src/app/generated/api/*.service.ts';

runCommand(gen, (error, stdout, stderr) => {
console.log('Output: ' + stdout)
if(error !== null){
console.log("Error: " + error);
return;
}
if(stderr !== null){
console.log("Stderr: " + stderr);
}
});

runCommand(rxFix, (error, stdout, stderr) => {
console.log('Output: ' + stdout)
if(error !== null){
console.log("Error: " + error);
return;
}
if(stderr !== null){
console.log("Stderr: " + stderr);
}
});

runCommand(frmFix, (error, stdout, stderr) => {
console.log('Output: ' + stdout)
if(error !== null){
console.log("Error: " + error);
return;
}
if(stderr !== null){
console.log("Stderr: " + stderr);
}
});

runCommand(frmFix2, (error, stdout, stderr) => {
console.log('Output: ' + stdout)
if(error !== null){
console.log("Error: " + error);
return;
}
if(stderr !== null){
console.log("Stderr: " + stderr);
}
});

Any news on this? Still facing the same issue...

this has been fixed by #9065 thanks everyone for help and sorry for delay.

Still have this issue with array type form-data parameters.
Version - latest

Was this page helpful?
0 / 5 - 0 ratings