1

I have a component that I would like to turn into an angular library, so I could use it in different projects.

This component uses a service, and it's injected as a dependency in a constructor.

  constructor(private myService: SomeService) {
  }

How should define this turning this component into a library as a property, so it would accept this service and inject it.

6
  • if it's dependencies are specified in it's own package.json you can just import them as normal service. Commented Feb 10, 2020 at 13:26
  • @Nicolas, yes, I thought about it. But, would you know, if there is another way, to pass a dependency or not? Commented Feb 10, 2020 at 13:30
  • Not really, this is the official way that Angular provide. Is there any limitation that prevent you from using this method ? Commented Feb 10, 2020 at 13:34
  • It's just the project that's going to use the library already uses this service, and I thought to just pass it down the library, instead of installing and configuring that same service into the library @Nicolas Commented Feb 10, 2020 at 13:36
  • @Nicolas, basically I do want to use the service the angular way, in the constructor, but I want it to come from the user of the library if at all possible. Commented Feb 10, 2020 at 13:38

1 Answer 1

3

You should take a look at Angular's official documentation on modules and singleton services and more specifically the forRoot method. The idea would be to create a module that declares your component. This module would need a forRoot() method, which gives ability to pass parameters when importing it in your application module (or any other module).

This question is really broad but the code would look like this (it's an idea and not fully functional):

Your library's module:

@NgModule({...})
export class LibraryModule {
  static forRoot(service: MyService): ModuleWithProviders {
    return {
      ngModule: LibraryModule,
      providers: [
        {provide: MyService, useClass: service}
      ]
    };
  }
}

Your application module that use your library module:

import { LibraryModule } from './library/my-module.module';
import { MyService } from './services/my-service.service';

@NgModule({
  imports: [
    LibraryModule.forRoot(MyService)
  ],
})

You can have a look at some existing libraries that use this technique. Angular's own router library expect the routes as a param of the forRoot() method.

Sign up to request clarification or add additional context in comments.

8 Comments

Thanks! Pretty sure this is what I need, just not completely sure about what I pass here forRoot(service: MyService). Do I create a class MyService in the library that describes what's going to get injected? @Guillaume
I would say: You want a lib with a component that use a service. But said service needs to be "dynamically" passed to the library by the component consumer (the module in which the component will be used). For this, you could create a service in the consumer module, that implements an interface. Said interface would be in the library. So any consumer module could declare its own service that adheres to the library's service interface specifications.
got it. Thank you.
You are welcome :) I wasn't sure my explanation war clear enough
It's clear. The funny thing is, it's not quite what I needed after all. And I guess I'm stumped at this point. Maybe I should open another question. Mainly the problem is, is that the main application uses translateModule (ngx-translate) and I want my module (that's separated) to be able to use it as well, the way main app uses it. Probably not clear at all
|

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.