25

I'm currently working on an Angular application (version 16.1.3) which utilizes standalone components. This application also relies on an Angular library that uses NgModules. I'm attempting to import a component from this library into my application, where the library also contains a function to retrieve environmental data from the application.

Here's the ui-lib.module.ts from the library

export class UiLibModule {
    public static forRoot(environment: any): ModuleWithProviders<UiLibModule> {
        return {
            ngModule: UiLibModule,
            providers: [
                {
                    provide: 'environment',
                    useValue: environment,
                },
            ],
        };
    }
}

In my main application, I'm importing the library within my main.ts file as follows:

bootstrapApplication(AppComponent, {
  providers: [
    importProvidersFrom(
    ...
    UiLibModule.forRoot(environment),
    ...)
    ]
...});

However, I'm experiencing a problem when I attempt to use a component from my library:

  • If I use a library component within my main app but outside of the <router-outlet></router-outlet>, everything works as expected.
  • If I use the same component from my library within a component that's routed within the <router-outlet></router-outlet>, I'm seeing issues. The component is displayed correctly, but upon leaving the page, the router fails to remove the component from the page. Moreover, no errors are displayed in the console.

Below is how I import the UiLibModule in my standalone components:

...
@Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.scss"],
  imports: [
    UiLibModule
  ]

I've tested this with libraries that utilize the .forRoot() function and libraries that do not. It appears that libraries that don't use .forRoot() work as expected, while those that do encounter the aforementioned issue.

My question pertains to the correct and complete inclusion of my library. I'm unsure if the current way I'm importing my library is accurate and comprehensive. Specifically, I'm curious whether there's a way to directly add the environment through the standalone component.

Additionally, I'm uncertain whether I need to declare the environment again within the standalone component, given that it has already been declared within the main.ts file.

Any guidance or suggestions regarding these questions would be greatly appreciated.

Thank you in advance.

1
  • I don't know the answer to your specific question, but when I had a similar problem with another NgModule, I found that changing the order of the bootstrap imports mattered. It may be worth trying re-ordering your imports in the providers array to see if that changes anything. Commented Jul 12, 2023 at 16:25

1 Answer 1

38

Probably too late your you, but for fellow devs having the same issue, you'll find the solution here: Angular Docs.

All you need is to use the importProvidersFrom() method.

As an example when trying to import Auth0's module:

export const appConfig: ApplicationConfig = {
  providers: [provideRouter(routes), importProvidersFrom(AuthModule.forRoot({
    // ... config
  }))]
};
Sign up to request clarification or add additional context in comments.

2 Comments

importProvidersFrom(...) was the missing piece for my case!
Yes, but a valuable addition would be, that importProvidersFrom is supposed to use only in application or environment injector, it means it should not be used in the component's providers only in application bootstrap.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.