How to pass injection token to nested service using SCAM approach (Single Component Angular Module)?

601 Views Asked by At

I have been playing with SCAM (Single Component Angular Modules) approach and I am facing a problem passing injection token from parent to child module.

I have a ScamService with httpClient and baseUrl injected:

import { HttpClient, HttpClientModule } from '@angular/common/http';
import { Injectable, Inject, NgModule, ModuleWithProviders } from '@angular/core';
import { BASE_URL } from './injection.tokens';

@Injectable()
export class ScamService {
  constructor( @Inject(BASE_URL) private baseUrl, private httpClient: HttpClient ) {}

  public getData() {
    return this.httpClient.get(`${this.baseUrl}/rest-of-endpoint`);
  }
}

@NgModule({
  imports: [HttpClientModule]
})
export class ScamServiceModule {
  public static forRoot(baseUrl): ModuleWithProviders<ScamServiceModule> {
    return {
      ngModule: ScamServiceModule,
      providers: [{
          provide: BASE_URL,
          useValue: baseUrl
      }]
    };
  }
}

To provide BASE_URL token to a module I need to create static method that returns ModuleWithProviders. There i am able to assign a value to the token. That's fine.

Next, I want to use the service in a component, so I am importing ScamServiceModule into ScamComponentModule:

import { Component, ModuleWithProviders, NgModule } from '@angular/core';
import { ScamService, ScamServiceModule } from './scam.service';

@Component({//...})
export class ScamComponent {
  constructor(private scamService: ScamService) {}
}

@NgModule({
  imports: [
    ScamServiceModule.forRoot(
      `The url I would like to pass is not in the environments, 
       I need to take it from forRoot of ScamComponentModule`
    )
  ]
})
export class ScamComponentModule {
  public static forRoot(baseUrl): ModuleWithProviders<ScamComponentModule> {
    // how to tell ScamServiceModule what the value of baseUrl is?
  }
}

Now I need to provide base url to it. So I should call ScamServiceModule.forRoot('some-url'). That would be fine If I knew the url on the component level.

But the url needs to be passed through forRoot method of ScamComponentModule.

Do you have any suggestion on how to pass the baseUrl through?

Thank you in advance!

1

There are 1 best solutions below

0
On

The problem has nothing to do with SCAM approach.

It`s just about providing dependencies. The solution to the problem is to use 'deps' property, alongside 'provide' and 'useValue' in Angular Providers array.