Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change NgModule configuration at runtime

There are some modules that expose their service configuration, for example:

  • AngularFireModule.initializeApp(firebaseConfig),
  • StoreModule.provideStore(reducer),
  • RouterModule.forRoot(routes)...

How would I reconfigure one of these at runtime? For example, user selects one of two links and different module is lazy loaded and configured differently... How can I pass data to this new NgModule?

All I can think of is to put something in global scope and read it from there, but... doesn't feel right :)

like image 459
Sasxa Avatar asked Oct 14 '16 00:10

Sasxa


People also ask

How do you specify the component is a member of an NgModule?

A component must belong to an NgModule in order for it to be usable by another component or application. To specify that a component is a member of an NgModule, you should list it in the declarations field of that NgModule.

Where is NgModule located?

The basic NgModulelinkAt the top are the import statements. The next section is where you configure the @NgModule by stating what components and directives belong to it ( declarations ) as well as which other modules it uses ( imports ).

What is the purpose of NgModule?

@NgModule takes a metadata object that describes how to compile a component's template and how to create an injector at runtime. It identifies the module's own components, directives, and pipes, making some of them public, through the exports property, so that external components can use them.


1 Answers

Providers can't be modified after the injector was created.

You can create a service that provides different instances depending on status.

@Injectable()
class ProviderService {
  constructor(injector:Injector) {}

  set firebaseConfig(firebaseConfig) {
    let resolvedProviders = ReflectiveInjector.resolve([AngularFireModule.initializeApp(firebaseConfig)]);
    this.childInjector = ReflectiveInjector.fromResolvedProviders(resolvedProviders, this.injector);    
  }

  get firebase ():AngularFireModule {
    return this.childInjector.get(AngularFireModule);
  }
}

and then use it like

class MyComponentOrService {
  constructor(provider:ProviderService) {}

  changeFirebase() {
    this.provider.firebaseConfig = ...;
    this.fb = this.provider.firebase;
  }

  doSomething() {
    this.fb.xxx();
  }
}
like image 195
Günter Zöchbauer Avatar answered Oct 24 '22 14:10

Günter Zöchbauer