I am trying to generate an API client from a v2 swagger file with openapi-generator-cli. For this I am using the docker container of openapi-generator-cli, which reports its version as '4.1.0-SNAPSHOT'.
Code generation works with the following options:
{
"npmName": "...",
"npmVersion": "0.0.3",
"snapshot": true,
"ngVersion": "8.1.1"
}
and I have also tried to set the providedInRoot
option to true.
However, the generated service classes are not annotated with the @Injectable
decorator. So after importing them in my component and adding the service in the constructor of the component, I am not able to use them. This is how my component looks like:
import { Component, OnInit } from '@angular/core';
import { UsersService, User } from '...'
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
constructor(userService: UsersService) {}
title = 'user-frontend';
ngOnInit() {
this.userService.listUsers();
}
}
which fails, because userService does not exist in the scope of AppComponent.
This is how I import the generated module:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { ApiModule } from '...';
import { HttpClientModule } from '@angular/common/http';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
ApiModule,
HttpClientModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Any ideas on where my error is when generating the api client?
EDIT: The generated code looks like this:
@Injectable({
providedIn: 'root'
})
export class UsersService {
protected basePath = 'http://localhost';
public defaultHeaders = new HttpHeaders();
public configuration = new Configuration();
public encoder: HttpParameterCodec;
constructor(protected httpClient: HttpClient, @Optional()@Inject(BASE_PATH) basePath: string, @Optional() configuration: Configuration) {
if (configuration) {
this.configuration = configuration;
this.configuration.basePath = configuration.basePath || basePath || this.basePath;
} else {
this.configuration.basePath = basePath || this.basePath;
}
this.encoder = this.configuration.encoder || new CustomHttpParameterCodec();
}
...
}
Alot of questions import { ApiModule } from '...'; where is code generated come from ? You publish it to npm and consume it or just copy paste the generated code? Try this
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HttpClientModule,
ApiModule.forRoot(() => {
return new Configuration({
basePath: `${environment.HOST}:${environment.PORT}`,
});
}),,
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Your generated code should like this
@Injectable({
providedIn: 'root'
})
export class PetsService {
protected basePath = 'http://localhost';
public defaultHeaders = new HttpHeaders();
public configuration = new Configuration();
constructor(protected httpClient: HttpClient, @Optional()@Inject(BASE_PATH) basePath: string, @Optional() configuration: Configuration) {
if (configuration) {
this.configuration = configuration;
this.configuration.basePath = configuration.basePath || basePath || this.basePath;
} else {
this.configuration.basePath = basePath || this.basePath;
}
}
Solution : use private or public in the constructor
Explanation: Here we have the same as your problem typescript dont know what you want
class TestClass {
constructor(name: string) {
}
}
Here we have last example in a normal POO promamming language
class TestClass {
private name: string;
constructor(name: string) {
this.name = name;
}
}
But typescript give us a easy way to minimize the code
class TestClass {
constructor(private name: string) { }
}