Skip to content

Commit

Permalink
[angular-typescript] fix using form data (swagger-api#6574)
Browse files Browse the repository at this point in the history
* swagger-api#6457: fix sending form params

* swagger-api#6457: fix sending form params using files

* swagger-api#6457: fix sending form params with files for angular 4.3

* swagger-api#6457: generate samples

* swagger-api#6457: [typescript-angular] fix form data submission in IE/Edge

* re-apply [typescript-angular] add customized encoder to use '+' char in query parameter swagger-api#6306 (swagger-api#6334)

* adapt for HttpClient: [typescript-angular] add customized encoder to use '+' char in query parameter swagger-api#6306 (swagger-api#6334)

* generate samples

* swagger-api#6457: fix url parameter encoder imports for angular <4.3

* swagger-api#6457: generate samples
  • Loading branch information
macjohnny authored and fvarose committed Oct 12, 2017
1 parent b29c514 commit e91fdf5
Show file tree
Hide file tree
Showing 24 changed files with 345 additions and 195 deletions.
Empty file modified bin/typescript-angular-v4.3-petstore-with-npm.sh
100644 → 100755
Empty file.
10 changes: 10 additions & 0 deletions bin/windows/typescript-angular-v4.3-with-npm.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
set executable=.\modules\swagger-codegen-cli\target\swagger-codegen-cli.jar

If Not Exist %executable% (
mvn clean package
)

REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M
set ags=generate -i modules\swagger-codegen\src\test\resources\2_0\petstore.yaml -c bin\typescript-petstore-npm.json -l typescript-angular -o samples\client\petstore\typescript-angular-v4.3\npm --additional-properties ngVersion=4.3

java %JAVA_OPTS% -jar %executable% %ags%
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,12 @@ import { {{classname}} } from '../{{filename}}';

import { BASE_PATH, COLLECTION_FORMATS } from '../variables';
import { Configuration } from '../configuration';
{{#useHttpClient}}
import { CustomHttpUrlEncodingCodec } from '../encoder';
{{/useHttpClient}}
{{^useHttpClient}}
import { CustomQueryEncoderHelper } from '../encoder';
{{/useHttpClient}}
{{#withInterfaces}}
import { {{classname}}Interface } from './{{classname}}Interface';
{{/withInterfaces}}
Expand Down Expand Up @@ -69,11 +74,6 @@ export class {{classname}} {
}


public isJsonMime(mime: string): boolean {
const jsonMime: RegExp = new RegExp('^(application\/json|[^;/ \t]+\/[^;/ \t]+[+]json)[ \t]*(;.*)?$', 'i');
return mime != null && (jsonMime.test(mime) || mime.toLowerCase() === 'application/json-patch+json');
}

{{^useHttpClient}}
{{! not sure why we used to generate a second method here rather than inlining those few lines of code,
but let's keep it for now for the sake of backwards compatiblity. }}
Expand Down Expand Up @@ -121,7 +121,12 @@ export class {{classname}} {
{{/allParams}}

{{#hasQueryParams}}
let queryParameters = new {{#useHttpClient}}HttpParams{{/useHttpClient}}{{^useHttpClient}}URLSearchParams{{/useHttpClient}}();
{{#useHttpClient}}
let queryParameters = new HttpParams({encoder: new CustomHttpUrlEncodingCodec()});
{{/useHttpClient}}
{{^useHttpClient}}
let queryParameters = new URLSearchParams('', new CustomQueryEncoderHelper());
{{/useHttpClient}}
{{#queryParams}}
{{#isListContainer}}
if ({{paramName}}) {
Expand Down Expand Up @@ -207,39 +212,59 @@ export class {{classname}} {
'{{{mediaType}}}'{{#hasMore}},{{/hasMore}}
{{/consumes}}
];
let canConsumeForm = this.canConsumeForm(consumes);
const canConsumeForm = this.canConsumeForm(consumes);

let formParams: { append(param: string, value: any): void; };
let useForm = false;
let convertFormParamsToString = false;
{{#formParams}}
{{#isFile}}
// use FormData to transmit files using content-type "multipart/form-data"
// see https://stackoverflow.com/questions/4007969/application-x-www-form-urlencoded-or-multipart-form-data
useForm = canConsumeForm;
{{/isFile}}
{{/formParams}}
let formParams = new (useForm ? FormData : URLSearchParams as any)() as {
set(param: string, value: any): void;
};
if (useForm) {
formParams = new FormData();
} else {
{{#useHttpClient}}
formParams = new HttpParams({encoder: new CustomHttpUrlEncodingCodec()});
{{/useHttpClient}}
{{^useHttpClient}}
// TODO: this fails if a parameter is a file, the api can't consume "multipart/form-data" and a blob is passed.
convertFormParamsToString = true;
formParams = new URLSearchParams('', new CustomQueryEncoderHelper());
// set the content-type explicitly to avoid having it set to 'text/plain'
headers.set('Content-Type', 'application/x-www-form-urlencoded;charset=UTF-8');
{{/useHttpClient}}
}



{{#formParams}}
{{#isListContainer}}
if ({{paramName}}) {
{{#isCollectionFormatMulti}}
{{paramName}}.forEach((element) => {
formParams.append('{{baseName}}', <any>element);
{{#useHttpClient}}formParams = {{/useHttpClient}}formParams.append('{{baseName}}', <any>element){{#useHttpClient}} || formParams{{/useHttpClient}};
})
{{/isCollectionFormatMulti}}
{{^isCollectionFormatMulti}}
formParams.set('{{baseName}}', {{paramName}}.join(COLLECTION_FORMATS['{{collectionFormat}}']));
{{#useHttpClient}}formParams = {{/useHttpClient}}formParams.append('{{baseName}}', {{paramName}}.join(COLLECTION_FORMATS['{{collectionFormat}}'])){{#useHttpClient}} || formParams{{/useHttpClient}};
{{/isCollectionFormatMulti}}
}
{{/isListContainer}}
{{^isListContainer}}
if ({{paramName}} !== undefined) {
formParams.set('{{baseName}}', <any>{{paramName}});
{{#useHttpClient}}formParams = {{/useHttpClient}}formParams.append('{{baseName}}', <any>{{paramName}}){{#useHttpClient}} || formParams{{/useHttpClient}};
}
{{/isListContainer}}
{{/formParams}}

{{/hasFormParams}}
{{#useHttpClient}}
return this.httpClient.{{httpMethod}}{{^isResponseFile}}<any>{{/isResponseFile}}(`${this.basePath}{{{path}}}`, {{#bodyParam}}{{paramName}}, {{/bodyParam}}{{#hasFormParams}}formParams, {{/hasFormParams}}{
return this.httpClient.{{httpMethod}}{{^isResponseFile}}<any>{{/isResponseFile}}(`${this.basePath}{{{path}}}`, {{#bodyParam}}{{paramName}}, {{/bodyParam}}
{{#hasFormParams}}convertFormParamsToString ? formParams.toString() : formParams, {{/hasFormParams}}{
{{#hasQueryParams}}
params: queryParameters,
{{/hasQueryParams}}
Expand All @@ -258,7 +283,7 @@ export class {{classname}} {
body: {{paramName}} == null ? '' : JSON.stringify({{paramName}}), // https://github.com/angular/angular/issues/10612
{{/bodyParam}}
{{#hasFormParams}}
body: formParams.toString(),
body: convertFormParamsToString ? formParams.toString() : formParams,
{{/hasFormParams}}
{{#isResponseFile}}
responseType: ResponseContentType.Blob,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,28 @@
import { QueryEncoder } from "@angular/http";
{{#useHttpClient}}
import { HttpUrlEncodingCodec } from '@angular/common/http';
{{/useHttpClient}}
{{^useHttpClient}}
import { QueryEncoder } from '@angular/http';
{{/useHttpClient}}

{{#useHttpClient}}
/**
* CustomHttpUrlEncodingCodec
* Fix plus sign (+) not encoding, so sent as blank space
* See: https://github.com/angular/angular/issues/11058#issuecomment-247367318
*/
export class CustomHttpUrlEncodingCodec extends HttpUrlEncodingCodec {
encodeKey(k: string): string {
k = super.encodeKey(k);
return k.replace(/\+/gi, '%2B');
}
encodeValue(v: string): string {
v = super.encodeValue(v);
return v.replace(/\+/gi, '%2B');
}
}
{{/useHttpClient}}
{{^useHttpClient}}
/**
* CustomQueryEncoderHelper
* Fix plus sign (+) not encoding, so sent as blank space
Expand All @@ -14,4 +37,6 @@ export class CustomQueryEncoderHelper extends QueryEncoder {
v = super.encodeValue(v);
return v.replace(/\+/gi, '%2B');
}
}
}
{{/useHttpClient}}

Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,6 @@ export class PetService {
}


public isJsonMime(mime: string): boolean {
const jsonMime: RegExp = new RegExp('^(application\/json|[^;/ \t]+\/[^;/ \t]+[+]json)[ \t]*(;.*)?$', 'i');
return mime != null && (jsonMime.test(mime) || mime.toLowerCase() === 'application/json-patch+json');
}

/**
*
* @summary Add a new pet to the store
Expand Down Expand Up @@ -282,7 +277,7 @@ export class PetService {
throw new Error('Required parameter status was null or undefined when calling findPetsByStatus.');
}

let queryParameters = new URLSearchParams();
let queryParameters = new URLSearchParams('', new CustomQueryEncoderHelper());
if (status) {
queryParameters.set('status', status.join(COLLECTION_FORMATS['csv']));
}
Expand Down Expand Up @@ -321,7 +316,7 @@ export class PetService {
throw new Error('Required parameter tags was null or undefined when calling findPetsByTags.');
}

let queryParameters = new URLSearchParams();
let queryParameters = new URLSearchParams('', new CustomQueryEncoderHelper());
if (tags) {
queryParameters.set('tags', tags.join(COLLECTION_FORMATS['csv']));
}
Expand Down Expand Up @@ -442,22 +437,34 @@ export class PetService {
let consumes: string[] = [
'application/x-www-form-urlencoded'
];
let canConsumeForm = this.canConsumeForm(consumes);
const canConsumeForm = this.canConsumeForm(consumes);

let formParams: { append(param: string, value: any): void; };
let useForm = false;
let formParams = new (useForm ? FormData : URLSearchParams as any)() as {
set(param: string, value: any): void;
};
let convertFormParamsToString = false;
if (useForm) {
formParams = new FormData();
} else {
// TODO: this fails if a parameter is a file, the api can't consume "multipart/form-data" and a blob is passed.
convertFormParamsToString = true;
formParams = new URLSearchParams('', new CustomQueryEncoderHelper());
// set the content-type explicitly to avoid having it set to 'text/plain'
headers.set('Content-Type', 'application/x-www-form-urlencoded;charset=UTF-8');
}



if (name !== undefined) {
formParams.set('name', <any>name);
formParams.append('name', <any>name);
}
if (status !== undefined) {
formParams.set('status', <any>status);
formParams.append('status', <any>status);
}

let requestOptions: RequestOptionsArgs = new RequestOptions({
method: RequestMethod.Post,
headers: headers,
body: formParams.toString(),
body: convertFormParamsToString ? formParams.toString() : formParams,
withCredentials:this.configuration.withCredentials
});
// https://github.com/swagger-api/swagger-codegen/issues/4037
Expand Down Expand Up @@ -494,23 +501,37 @@ export class PetService {
let consumes: string[] = [
'multipart/form-data'
];
let canConsumeForm = this.canConsumeForm(consumes);
const canConsumeForm = this.canConsumeForm(consumes);

let formParams: { append(param: string, value: any): void; };
let useForm = false;
let convertFormParamsToString = false;
// use FormData to transmit files using content-type "multipart/form-data"
// see https://stackoverflow.com/questions/4007969/application-x-www-form-urlencoded-or-multipart-form-data
useForm = canConsumeForm;
let formParams = new (useForm ? FormData : URLSearchParams as any)() as {
set(param: string, value: any): void;
};
if (useForm) {
formParams = new FormData();
} else {
// TODO: this fails if a parameter is a file, the api can't consume "multipart/form-data" and a blob is passed.
convertFormParamsToString = true;
formParams = new URLSearchParams('', new CustomQueryEncoderHelper());
// set the content-type explicitly to avoid having it set to 'text/plain'
headers.set('Content-Type', 'application/x-www-form-urlencoded;charset=UTF-8');
}



if (additionalMetadata !== undefined) {
formParams.set('additionalMetadata', <any>additionalMetadata);
formParams.append('additionalMetadata', <any>additionalMetadata);
}
if (file !== undefined) {
formParams.set('file', <any>file);
formParams.append('file', <any>file);
}

let requestOptions: RequestOptionsArgs = new RequestOptions({
method: RequestMethod.Post,
headers: headers,
body: formParams.toString(),
body: convertFormParamsToString ? formParams.toString() : formParams,
withCredentials:this.configuration.withCredentials
});
// https://github.com/swagger-api/swagger-codegen/issues/4037
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,6 @@ export class StoreService {
}


public isJsonMime(mime: string): boolean {
const jsonMime: RegExp = new RegExp('^(application\/json|[^;/ \t]+\/[^;/ \t]+[+]json)[ \t]*(;.*)?$', 'i');
return mime != null && (jsonMime.test(mime) || mime.toLowerCase() === 'application/json-patch+json');
}

/**
* For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors
* @summary Delete purchase order by ID
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,6 @@ export class UserService {
}


public isJsonMime(mime: string): boolean {
const jsonMime: RegExp = new RegExp('^(application\/json|[^;/ \t]+\/[^;/ \t]+[+]json)[ \t]*(;.*)?$', 'i');
return mime != null && (jsonMime.test(mime) || mime.toLowerCase() === 'application/json-patch+json');
}

/**
* This can only be done by the logged in user.
* @summary Create user
Expand Down Expand Up @@ -342,7 +337,7 @@ export class UserService {
throw new Error('Required parameter password was null or undefined when calling loginUser.');
}

let queryParameters = new URLSearchParams();
let queryParameters = new URLSearchParams('', new CustomQueryEncoderHelper());
if (username !== undefined) {
queryParameters.set('username', <any>username);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { QueryEncoder } from "@angular/http";
import { QueryEncoder } from '@angular/http';

/**
* CustomQueryEncoderHelper
Expand All @@ -14,4 +14,5 @@ export class CustomQueryEncoderHelper extends QueryEncoder {
v = super.encodeValue(v);
return v.replace(/\+/gi, '%2B');
}
}
}

Loading

0 comments on commit e91fdf5

Please sign in to comment.