2

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();
    }

...
}
2
  • Have you try to put ApiModule in providers array? Commented Jul 30, 2019 at 7:36
  • @AugustinR, I just tried that, but it did not help Commented Jul 30, 2019 at 8:10

1 Answer 1

5

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) { }
}
Sign up to request clarification or add additional context in comments.

10 Comments

Thanks for the tip, unfortunately I still get the same error. To answer your question, I publish the generated code to a private npm und consume it from there. Since I can import the ApiModule, classes and so on, I am quite confident that this part works. Could you hint at why the different ways of bringing the ApiModule into my project could lead to such an error?
You generate the code and convert it to a angular library with ng-packagr?
Exactly, I generate the code, switch to the folder with the generated code, then I run: npm install, next npm run build (which executes ng-packagr), then I log in to my npm registry and do a npm publish dist to my registry.
I got the same so seems like is a template issue check my edit above and tell me if you generate code its something like that
Thanks for your help, I edited my question and appended the exported UsersService class. Looks the same for me.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.