Skip to content
This repository was archived by the owner on Dec 25, 2024. It is now read-only.

Commit 54e712a

Browse files
authored
fix(typescript-angular): compile error with queryParamObjectFormat and tsc --strictNullChecks (#13431)
fixes #13429
1 parent af0c9d2 commit 54e712a

File tree

25 files changed

+2554
-1
lines changed

25 files changed

+2554
-1
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
generatorName: typescript-angular
2+
outputDir: samples/client/petstore/typescript-angular-v14-query-param-object-format
3+
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
4+
templateDir: modules/openapi-generator/src/main/resources/typescript-angular
5+
additionalProperties:
6+
ngVersion: 14.0.5
7+
supportsES6: true
8+
queryParamObjectFormat: json

modules/openapi-generator/src/main/resources/typescript-angular/api.service.mustache

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,11 @@ export class {{classname}} {
121121

122122
if (typeof value === "object") {
123123
{{#isQueryParamObjectFormatJson}}
124-
httpParams = httpParams.append(key, JSON.stringify(value));
124+
if (key != null) {
125+
httpParams = httpParams.append(key, JSON.stringify(value));
126+
} else {
127+
throw Error("key may not be null if value is a QueryParamObject");
128+
}
125129
{{/isQueryParamObjectFormatJson}}
126130
{{^isQueryParamObjectFormatJson}}
127131
if (Array.isArray(value)) {
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
wwwroot/*.js
2+
node_modules
3+
typings
4+
dist
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# OpenAPI Generator Ignore
2+
# Generated by openapi-generator https://github.com/openapitools/openapi-generator
3+
4+
# Use this file to prevent files from being overwritten by the generator.
5+
# The patterns follow closely to .gitignore or .dockerignore.
6+
7+
# As an example, the C# client generator defines ApiClient.cs.
8+
# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
9+
#ApiClient.cs
10+
11+
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
12+
#foo/*/qux
13+
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
14+
15+
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
16+
#foo/**/qux
17+
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
18+
19+
# You can also negate patterns with an exclamation (!).
20+
# For example, you can ignore all files in a docs folder with the file extension .md:
21+
#docs/*.md
22+
# Then explicitly reverse the ignore rule for a single file:
23+
#!docs/README.md
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
.gitignore
2+
README.md
3+
api.module.ts
4+
api/api.ts
5+
api/pet.service.ts
6+
api/store.service.ts
7+
api/user.service.ts
8+
configuration.ts
9+
encoder.ts
10+
git_push.sh
11+
index.ts
12+
model/apiResponse.ts
13+
model/category.ts
14+
model/models.ts
15+
model/order.ts
16+
model/pet.ts
17+
model/tag.ts
18+
model/user.ts
19+
param.ts
20+
variables.ts
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
6.1.1-SNAPSHOT
Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
## @
2+
3+
### Building
4+
5+
To install the required dependencies and to build the typescript sources run:
6+
```
7+
npm install
8+
npm run build
9+
```
10+
11+
### publishing
12+
13+
First build the package then run ```npm publish dist``` (don't forget to specify the `dist` folder!)
14+
15+
### consuming
16+
17+
Navigate to the folder of your consuming project and run one of next commands.
18+
19+
_published:_
20+
21+
```
22+
npm install @ --save
23+
```
24+
25+
_without publishing (not recommended):_
26+
27+
```
28+
npm install PATH_TO_GENERATED_PACKAGE/dist.tgz --save
29+
```
30+
31+
_It's important to take the tgz file, otherwise you'll get trouble with links on windows_
32+
33+
_using `npm link`:_
34+
35+
In PATH_TO_GENERATED_PACKAGE/dist:
36+
```
37+
npm link
38+
```
39+
40+
In your project:
41+
```
42+
npm link
43+
```
44+
45+
__Note for Windows users:__ The Angular CLI has troubles to use linked npm packages.
46+
Please refer to this issue https://github.com/angular/angular-cli/issues/8284 for a solution / workaround.
47+
Published packages are not effected by this issue.
48+
49+
50+
#### General usage
51+
52+
In your Angular project:
53+
54+
55+
```
56+
// without configuring providers
57+
import { ApiModule } from '';
58+
import { HttpClientModule } from '@angular/common/http';
59+
60+
@NgModule({
61+
imports: [
62+
ApiModule,
63+
// make sure to import the HttpClientModule in the AppModule only,
64+
// see https://github.com/angular/angular/issues/20575
65+
HttpClientModule
66+
],
67+
declarations: [ AppComponent ],
68+
providers: [],
69+
bootstrap: [ AppComponent ]
70+
})
71+
export class AppModule {}
72+
```
73+
74+
```
75+
// configuring providers
76+
import { ApiModule, Configuration, ConfigurationParameters } from '';
77+
78+
export function apiConfigFactory (): Configuration {
79+
const params: ConfigurationParameters = {
80+
// set configuration parameters here.
81+
}
82+
return new Configuration(params);
83+
}
84+
85+
@NgModule({
86+
imports: [ ApiModule.forRoot(apiConfigFactory) ],
87+
declarations: [ AppComponent ],
88+
providers: [],
89+
bootstrap: [ AppComponent ]
90+
})
91+
export class AppModule {}
92+
```
93+
94+
```
95+
// configuring providers with an authentication service that manages your access tokens
96+
import { ApiModule, Configuration } from '';
97+
98+
@NgModule({
99+
imports: [ ApiModule ],
100+
declarations: [ AppComponent ],
101+
providers: [
102+
{
103+
provide: Configuration,
104+
useFactory: (authService: AuthService) => new Configuration(
105+
{
106+
basePath: environment.apiUrl,
107+
accessToken: authService.getAccessToken.bind(authService)
108+
}
109+
),
110+
deps: [AuthService],
111+
multi: false
112+
}
113+
],
114+
bootstrap: [ AppComponent ]
115+
})
116+
export class AppModule {}
117+
```
118+
119+
```
120+
import { DefaultApi } from '';
121+
122+
export class AppComponent {
123+
constructor(private apiGateway: DefaultApi) { }
124+
}
125+
```
126+
127+
Note: The ApiModule is restricted to being instantiated once app wide.
128+
This is to ensure that all services are treated as singletons.
129+
130+
#### Using multiple OpenAPI files / APIs / ApiModules
131+
In order to use multiple `ApiModules` generated from different OpenAPI files,
132+
you can create an alias name when importing the modules
133+
in order to avoid naming conflicts:
134+
```
135+
import { ApiModule } from 'my-api-path';
136+
import { ApiModule as OtherApiModule } from 'my-other-api-path';
137+
import { HttpClientModule } from '@angular/common/http';
138+
139+
@NgModule({
140+
imports: [
141+
ApiModule,
142+
OtherApiModule,
143+
// make sure to import the HttpClientModule in the AppModule only,
144+
// see https://github.com/angular/angular/issues/20575
145+
HttpClientModule
146+
]
147+
})
148+
export class AppModule {
149+
150+
}
151+
```
152+
153+
154+
### Set service base path
155+
If different than the generated base path, during app bootstrap, you can provide the base path to your service.
156+
157+
```
158+
import { BASE_PATH } from '';
159+
160+
bootstrap(AppComponent, [
161+
{ provide: BASE_PATH, useValue: 'https://your-web-service.com' },
162+
]);
163+
```
164+
or
165+
166+
```
167+
import { BASE_PATH } from '';
168+
169+
@NgModule({
170+
imports: [],
171+
declarations: [ AppComponent ],
172+
providers: [ provide: BASE_PATH, useValue: 'https://your-web-service.com' ],
173+
bootstrap: [ AppComponent ]
174+
})
175+
export class AppModule {}
176+
```
177+
178+
179+
#### Using @angular/cli
180+
First extend your `src/environments/*.ts` files by adding the corresponding base path:
181+
182+
```
183+
export const environment = {
184+
production: false,
185+
API_BASE_PATH: 'http://127.0.0.1:8080'
186+
};
187+
```
188+
189+
In the src/app/app.module.ts:
190+
```
191+
import { BASE_PATH } from '';
192+
import { environment } from '../environments/environment';
193+
194+
@NgModule({
195+
declarations: [
196+
AppComponent
197+
],
198+
imports: [ ],
199+
providers: [{ provide: BASE_PATH, useValue: environment.API_BASE_PATH }],
200+
bootstrap: [ AppComponent ]
201+
})
202+
export class AppModule { }
203+
```
204+
205+
### Customizing path parameter encoding
206+
207+
Without further customization, only [path-parameters][parameter-locations-url] of [style][style-values-url] 'simple'
208+
and Dates for format 'date-time' are encoded correctly.
209+
210+
Other styles (e.g. "matrix") are not that easy to encode
211+
and thus are best delegated to other libraries (e.g.: [@honoluluhenk/http-param-expander]).
212+
213+
To implement your own parameter encoding (or call another library),
214+
pass an arrow-function or method-reference to the `encodeParam` property of the Configuration-object
215+
(see [General Usage](#general-usage) above).
216+
217+
Example value for use in your Configuration-Provider:
218+
```typescript
219+
new Configuration({
220+
encodeParam: (param: Param) => myFancyParamEncoder(param),
221+
})
222+
```
223+
224+
[parameter-locations-url]: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#parameter-locations
225+
[style-values-url]: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#style-values
226+
[@honoluluhenk/http-param-expander]: https://www.npmjs.com/package/@honoluluhenk/http-param-expander
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { NgModule, ModuleWithProviders, SkipSelf, Optional } from '@angular/core';
2+
import { Configuration } from './configuration';
3+
import { HttpClient } from '@angular/common/http';
4+
5+
import { PetService } from './api/pet.service';
6+
import { StoreService } from './api/store.service';
7+
import { UserService } from './api/user.service';
8+
9+
@NgModule({
10+
imports: [],
11+
declarations: [],
12+
exports: [],
13+
providers: []
14+
})
15+
export class ApiModule {
16+
public static forRoot(configurationFactory: () => Configuration): ModuleWithProviders<ApiModule> {
17+
return {
18+
ngModule: ApiModule,
19+
providers: [ { provide: Configuration, useFactory: configurationFactory } ]
20+
};
21+
}
22+
23+
constructor( @Optional() @SkipSelf() parentModule: ApiModule,
24+
@Optional() http: HttpClient) {
25+
if (parentModule) {
26+
throw new Error('ApiModule is already loaded. Import in your base AppModule only.');
27+
}
28+
if (!http) {
29+
throw new Error('You need to import the HttpClientModule in your AppModule! \n' +
30+
'See also https://github.com/angular/angular/issues/20575');
31+
}
32+
}
33+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export * from './pet.service';
2+
import { PetService } from './pet.service';
3+
export * from './store.service';
4+
import { StoreService } from './store.service';
5+
export * from './user.service';
6+
import { UserService } from './user.service';
7+
export const APIS = [PetService, StoreService, UserService];

0 commit comments

Comments
 (0)