Angular module with customizable configurations

I am interested in developing a customizable Angular 9 module with IVY and AOT enabled.

In the latest version of Angular, IVY and AOT are automatically activated:

npx @angular/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="ed8e8184add4c3ddc3db">[email protected]</a> new ng-modules --style=scss --routing=false

The goal is to create a single stateful service within the module that can be configured by its name:

counter.module.ts

@Injectable()
export class CounterService {
  private counter = 0;
  shoot() {
    return this.counter++;
  }
}

@NgModule()
export class CounterModule {
  static withConfig(name: string): ModuleWithProviders {
    return {
      ngModule: CounterModule,
      providers: [{
        provide: name,
        useClass: CounterService
      }]
    };
  }
}

app.module.ts

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    CounterModule.withConfig('main.CountService'),
    CounterModule.withConfig('integration.CountService'),
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

app.component.ts

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  title = 'ng-modules-shots';
  constructor(
    @Inject('main.CountService') counter: CounterService,
  ) {
    this.title = '' + counter.shoot();
  }

}

Everything behaves as expected at this point. However, when attempting to modify CounterModule.withConfig, I encounter an issue:

counter.module.ts

...
@NgModule()
export class CounterModule {
  static withConfig(name?: string): ModuleWithProviders {
    const counterProviderToken = name ? name : CounterService;
    return {
      ngModule: CounterModule,
      providers: [{
        provide: counterProviderToken,
        useClass: CounterService
      }]
    };
  }
}

An error message appears:

ERROR in src/app/app.module.ts:11:16 - error NG1010: Value at position 1 in the NgModule.imports of AppModule is not a reference: [object Object]

What steps should be taken to resolve this issue? Is there an alternative method for creating configurable modules?

Answer №1

In the current scenario, there is a restriction that allows only a single statement in the function. Therefore, if you wish to incorporate any logic while ensuring Ahead-of-Time (AOT) compilation works properly, it must be contained within this statement.

...
@NgModule()
export class CounterModule {
  static withConfig(name?: string): ModuleWithProviders {
    return {
      ngModule: CounterModule,
      providers: [{
        provide: name ? name : CounterService,
        useClass: CounterService
      }]
    };
  }
}

However, you have the option of utilizing a function to generate providers within this module:

...
@NgModule()
export class CounterModule {
  static withConfig(name?: string): ModuleWithProviders {
    return {
      ngModule: CounterModule,
      providers: this.generateProviders(name)
    };
  }

  private static generateProviders(name?: string): Provider[] {
    const counterProviderToken = name ? name : CounterService;
    return [{
      provide: counterProviderToken,
      useClass: CounterService
    }]
  }
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is there a way to effectively eliminate an array of objects in JavaScript or TypeScript and alter the object structure simultaneously?

I am seeking solutions to restructure an object that has multiple arrays of objects so that I can access the object directly. console.log(value.data.summary[0].data) Instead of accessing arrays in this manner, I want to modify my data structure. Is there ...

The matInput directive is experiencing issues when used in a module that is loaded laz

After implementing a lazy loading module, I encountered an issue where elements like matInput were not displaying correctly. Even though the MatInputModule was imported in the module as expected: const routes = [ {path: '', component: AddPlace ...

Access the Angular application directly from the email

Our infrastructure consists of a .NET back-end, an Angular 5 application, and a nginx server. Upon registering your account in the application, you will receive an email with a verification link structured as follows: [root]/register/verify?userId=blabla& ...

Encountering a "No exported member" error while attempting to include & { session: Express.Session } in the MyContext type while following a tutorial on React, Express, and Typescript

Currently exploring a React, Express, and Typescript tutorial, which is still quite new to me. I am trying to grasp the concept of setting up custom types, and this is what I have so far. In my types.ts file: import { Request, Response } from "expres ...

Encountering an error when using Jest and the envalid library to test a React application: process.exit invoked with code "1"

While testing my React/Typescript application with Jest, I encountered an error. I am utilizing the envalid library to manage my environment variables with types and autocompletion: const ENV = cleanEnv(process.env, { | ^ 6 | R ...

The type 'Event' argument cannot be assigned to the 'InfiniteScrollCustomEvent' parameter

I'm facing an issue with Ionic Angular. Here is my movies.page.html: <ion-header> <ion-toolbar color="primary"> <ion-title>Trending Movies</ion-title> </ion-toolbar> </ion-header> <ion-content ...

Consolidating Typescript modules into a single .js file

Recently, I was able to get my hands on a TypeScript library that I found on GitHub. As I started exploring it, I noticed that there were quite a few dependencies on other npm packages. This got me thinking - is there a way to compile all these files int ...

Tracking errors, recording their occurrences, and sending them to Google Analytics: A step-by-step guide

In my code, I have an interceptor that redirects to the route /page-error whenever there is an API error. return next.handle(request.clone()).pipe( catchError((err: any) => { this.router.navigate(['/page-error']); ret ...

Using Regular Expressions: Ensuring that a specific character is immediately followed by one or multiple digits

Check out the regular expression I created: ^[0-9\(\)\*\+\/\-\sd]*$ This regex is designed to match patterns such as: '2d6', '(3d6) + 3', and more. However, it also mistakenly matches: '3d&apos ...

The error occurs when trying to access the `pipe` property of an undefined variable in NgbTypeahead

I am currently working on implementing the typeahead directive of ng-bootstrap. Below is the code snippet from my HTML file: <input type="text" class="form-control" formControlName="payee" autofocus [ngbTypeahead]="searchPayee"> Here's the cor ...

Encountered the "Error TS2300: Duplicate identifier 'Account'" issue following the upgrade to Typescript version 2.9.1

Since upgrading to Typescript 2.9.1 (from 2.8), I encountered a compile error: node_modules/typescript/lib/lib.es2017.full.d.ts:33:11 - error TS2300: Duplicate identifier 'Account'. This issue never occurred when I was using typescript 2.7 and ...

When hovering over one div, both it and another div should be displayed simultaneously. The second div should continue to be displayed even when hovered over

I am looking to keep another div displayed when hovering over it - in this example, it says "hello." The div I want to remain visible is not a child element of the main div where I initiate the hover event. document.write("<base href=\"" + docum ...

Clear the input field once an item has been successfully added to the array

I'm working on a CRUD application using an array. Once I add an item to the array, the HTML input field doesn't clear or reset. I've searched online but couldn't find a reset method in Angular. How can I clear the input field after addi ...

"Unexpected outcome: Angular's HTTP request for a JSON file yields an undefined

Learning Angular has been a challenging experience for me. I am currently working on reading a json file into a chart on my main app page to visualize temperature data from my PI. Despite trying various methods found online, I have not been successful so f ...

Angular 5 Reactive Forms - harnessing the power of multiple forms within a single view template

One innovative approach I'm considering is the ability to support multiple forms on a single view template and then display only the relevant form based on user interaction. Initially, I have a HOST node and a LOCATION node grouped under one [formGro ...

Can an enum be declared in Typescript without specifying a type explicitly?

Within an interface, I have a group of 10+ (optional) members, most of which have a specific set of potential values. To streamline this, I would like to utilize enums. However, creating separate enum types for each member (which are only used once and hav ...

The attribute interface overload in Typescript is an important concept to

Consider a scenario where there are multiple payload options available: interface IOne { type: 'One', payload: { name: string, age: number } } interface ITwo { type: 'Two', payload: string } declare type TBoth = IOne ...

Issues with applying panelClass on panels in ng2-bootstrap library for Angular 2

In the ng2-bootstrap documentation, it mentions a panelClass annotation that can be used for panels. However, I am having trouble getting it to work properly. Here is the code I am using: <accordion> <accordion-group [panelClass]="panel-primary" ...

Support for Chrome in Angular 8

Can someone please advise on the minimum version of Google Chrome that is supported by Angular 8? Additionally, I am looking for a way to prompt users to update their Chrome browser if it doesn't meet the required version. My Angular application seems ...

The issue with collapsible elements not functioning properly in an Angular application involving CSS and JS

My implementation of collapsible in a plain HTML page looks like this: <!DOCTYPE html> <html> <head> <title></title> <style> button.accordion { background-color: #777; color: white; cursor: pointer; p ...