Swagger-codegen: [typescript-angular2] baseUrl injectable

Created on 3 Aug 2016  路  9Comments  路  Source: swagger-api/swagger-codegen

Description

The constructors for the Api classes in typescript-angular2 currently have the definition:

constructor(protected http: Http, @Optional() basePath: string)

To be able to provide a value and have DI use this value, would it be better to set this up as:

constructor(protected http: Http,  @Optional()@Inject(BASE_PATH) basePath: string)

And define a variables file with:

export const BASE_PATH = new OpaqueToken('basePath');

And then this could be utilised on app bootstrap by:

Import { BASE_PATH } from './service/variables';
bootstrap(AppComponent, [
    { provide: BASE_PATH, useValue: 'http://myservice:5000' }
]);
Swagger-codegen version

2.2.0

I'd be happy to make the contribution via a PR, just checking that there is no prior agreed way. And that this would be an appropriate way to handle this case?

TypeScript General

Most helpful comment

@wdunn001
I used the following way of "renaming" to provide two BASE_PATH:

.....
import { BASE_PATH as StorageUrl } from './services/storageApi/variables';
import { BASE_PATH as CalculationUrl } from './services/calculationApi/variables';

@NgModule({
  declarations: [...],
  imports: [...],
  bootstrap: [AppComponent],
  providers: [
      { provide: StorageUrl, useValue: 'http://localhost:8080' },
      { provide: CalculationUrl, useValue: 'http://localhost:8090' }
  ]

All 9 comments

PR merged into master. Please pull the latest master for this enhancement.

in this scenario how would you provide a BASE_PATH for multiple API's ? for example if you had a authentication web api and a appdata api that lived on different servers.

@wdunn001 I've thought I might come up against this same problem and am not sure how to make it work at the moment. I know with angular 4.x OpaqueToken was deprecated in favour of InjectionToken<?> so maybe that has some added functionality that could be used.
Happy to have anyone else with some thoughts on this problem...

@wdunn001
I used the following way of "renaming" to provide two BASE_PATH:

.....
import { BASE_PATH as StorageUrl } from './services/storageApi/variables';
import { BASE_PATH as CalculationUrl } from './services/calculationApi/variables';

@NgModule({
  declarations: [...],
  imports: [...],
  bootstrap: [AppComponent],
  providers: [
      { provide: StorageUrl, useValue: 'http://localhost:8080' },
      { provide: CalculationUrl, useValue: 'http://localhost:8090' }
  ]

@einStefan how does this work? wouldnt the second instance of provider just rename both BASE_PATH vars?

@wdunn001
I found this feature in the TypeScript documentation. (look for "Import a single export from a module" section at: https://www.typescriptlang.org/docs/handbook/modules.html)

Don't know how it works, sorry.
I'm using it as described above and it works for my project.

@damienpontifex InjectionToken<?> doesn't change how the injector works, but it does add type information, so when you use the provider you get some type checking.

With regards to having two BASE_URLs, Angular uses Hierarchial Injectors, which essentially means it tries to use the nearest parent for injecting a value/component. So one of the ways to solve this issue is to have the API provided by different modules, each module providing a different BASE_URL.

I'm surprised to see @einStefan 's example working, because I don't know how the generated API would know to ask for the StorageUrl to be injected. I'm going to try to see if I can replicate. Can you show us a snippet of one of your API classes?

@iblocks-Xander, @wdunn001
After some googeling i have learned what I'm using there :).
It is possible to use an alias for the Import.
It seems to be a JavaScript Feature which is described here:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import

Here is another example:
http://stackoverflow.com/a/39610348/2753886

@einStefan
Your example works due to having two APIs (And two BASE_PATH objects) I think. If you tried to alias the same BASE_PATH, it is still referring to the same OpaqueToken Object.
The injection points in the generated APIs aren't referring to the aliases, so they will just inject the OpaqueToken value.

When I tried to reproduce with a minimal example, the BASE_PATH injected depended on which one had been last provided (In this example BASE_PATH has a value of "localhost")

// app.module.ts
...
import {BASE_PATH as t1 } from './gen/variables';
import {BASE_PATH as t2 } from './gen/variables';
...
providers: [{
        provide: t1,
        useValue: "unlocalhost"
    },{
        provide: t2,
        useValue: "localhost"
    }]

Looking at your example again, I think your example works because there are actually two BASE_PATH objects, so I imagine in your classes you import a specific BASE_PATH by specifying the directory.

If you had one API that you would like to specify multiple BASE_PATHs for, I think you would have to do this differently. Although, I suppose having different BASE_PATHs for a single API is unlikely!

Was this page helpful?
0 / 5 - 0 ratings