I would like to reuse some Angular 6 API services in a node script and am facing some troubles initialising everything properly.
The API services are generated using Swagger Codegen (-l typescript-angular
), which gives me for example:
@Injectable()
export class UserService {
constructor(protected httpClient: HttpClient, @Optional()@Inject(BASE_PATH) basePath: string, @Optional() configuration: Configuration) {
...
}
}
These services work perfect in my Angular 6 application and I would now like to use them in a node for some scripting. I'm aware that Swagger Codegen is also able to generate a pure Typescript client, but would still prefer to reuse the existing Angular services to keep the code base more in line.
The challenge I'm then facing is how to call this constructor without dependency injection.
It appears to be very hard to get a valid HttpClient
object without dependency injection. In AngularJS I used to rely on Axios for this, but that library does not provide the same interface as HttpClient
any more it seems (still promises instead of the newer observables in Angular 6).
It seems to me there would be two options:
HttpClient
object -> can't get this to work.Does anybody know how to properly tackle this?
Cheers,
M.
HttpClient
isn't supposed to be manually instantiated and this isn't straightforward process because it has a lot of dependencies. Angular injector does all the work on dependency injection and should be used to get an instance.
As shown in this answer, it's possible to get an instance of Angular provider (HttpClient
) by setting up a module and bootstrapping it.
A very similar approach should be used for UserService
. Here is simplified but workable example:
import 'zone.js/dist/zone-node';
import 'reflect-metadata';
import {Injector, Injectable, NgModule } from '@angular/core'
import {HttpClient, HttpClientModule} from '@angular/common/http'
import {ServerModule, platformDynamicServer} from '@angular/platform-server';
@Injectable()
export class UserService {
constructor(protected httpClient: HttpClient) {
httpClient.get('https://google.com/').subscribe(console.log, console.error);
}
}
@NgModule({
imports: [ServerModule, HttpClientModule],
providers: [UserService]
})
export class AppModule {
ngDoBootstrap() {}
}
(async () => {
const platform = platformDynamicServer();
const appModule = await platform.bootstrapModule(AppModule);
const userService = appModule.injector.get(UserService);
})()
.catch(console.error);
It needs a compatible TypeScript configuration, e.g.:
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"strict": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With