Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ability to add services to modal injector #5275

Closed
rseanhall opened this issue Jun 14, 2019 · 4 comments · Fixed by #5276
Closed

Ability to add services to modal injector #5275

rseanhall opened this issue Jun 14, 2019 · 4 comments · Fixed by #5276

Comments

@rseanhall
Copy link
Contributor

Currently, BsModalService does not give the ability to provide services through injection. It is hardcoded to provide the ModalOptions and BsModalRef service in _showModal. I have a service that needs to be injected deep into the component tree where it is impractical to pass it through using initialState and Inputs. ModalOptions should expose a providers?: StaticProvider[] property so that the caller can add more providers to the injector.

rseanhall pushed a commit to rseanhall/ngx-bootstrap that referenced this issue Jun 14, 2019
Add providers property to ModalOptions so that services can be added to the injector for the modal.

Closes valor-software#5275.
rseanhall added a commit to rseanhall/ngx-bootstrap that referenced this issue Jun 14, 2019
Add providers property to ModalOptions so that services can be added to the injector for the modal.

Closes valor-software#5275.
valorkin added a commit that referenced this issue Jan 31, 2020
Add providers property to ModalOptions so that services can be added to the injector for the modal.

Closes #5275.

Co-authored-by: Dmitriy Danilov <daniloff200@gmail.com>
Co-authored-by: Dmitriy Shekhovtsov <valorkin@gmail.com>
@eLeontev
Copy link

eLeontev commented Mar 12, 2021

this feature works only if providers has no other DI or providers are registered as part of root module. The issue is the injector used in the modal is rootInjector and all DI registered in different modules does not exists in it.

Example:

@Component()
export class RootModalComponent {
  constructor(rootComponentModalService: RootComponentModalService) {}
}

@Component()
export class FeatureModalComponent {
  constructor(featureComponentModalService: FeatureComponentModalService) {}
}

@Component()
export class FeatureWithDIModalComponent {
  constructor(featureWithOtherDIService: FeatureWithOtherDIService) {}
}

@Injectable()
export class FeatureComponentModalService {}

@Injectable()
export class FeatureWithOtherDIService {
  constructor(featureWithoutDIService: FeatureWithoutDIService) {}
}

@Injectable()
export class FeatureWithoutDIService {}

@NgModule({
   imports: [FeatureModule],
   declarations: [RootModalComponent],
   providers: [RootComponentModalService]
})
export class RootModule {}

@NgModule({
   declarations: [FeatureModalComponent, FeatureWithDIModalComponent],
   providers: [FeatureComponentModalService, FeatureWithOtherDIService, FeatureWithoutDIService]
})
export class FeatureModule {}

platform.bootstrapModule(RootModule)

// usage
bsModalService.show(RootModalComponent) // works as expected

// dependecy is not provided for RootModule and cannot be found
bsModalService.show(FeatureModalComponent) //  injection error
bsModalService.show(FeatureModalComponent, {providers: [FeatureComponentModalService]}) //  works as expected

// first dependency is provided but cannot be injected since its dependency (FeatureWithoutDIService) is not found
bsModalService.show(FeatureModalComponent, {providers: [FeatureComponentModalService]}) //  injection error
bsModalService.show(FeatureModalComponent, {providers: [FeatureComponentModalService, FeatureWithoutDIService]}) //  works as expected

I hope the examples are readable :)

Hacks:

  1. register all services to rootModule (bad solution leads to increase of main bundle size)
  2. use only services without other dependencies (if it make sense for your logic)
  3. pass all dependent services to providers options (can be weird with a lot of dependencies)

If it will be fixed (proposal):
add additional field for options to define the injector from which the modal will be created.

for now it works:

let modalInjector({
  providers: options.providers,
  parent: rootInjector //  this._injector in the code
})

to next view:

let modalInjector({
  providers: options.providers,
  parent: options.parentInjector || rootInjector
})

@rseanhall
Copy link
Contributor Author

My use case was:

  1. use only services without other dependencies (if it make sense for your logic)

It was the responsibility of the code calling bsModalService.show to resolve dependencies. It sounds like you want a new feature. You probably should create a separate issue for that.

@d0r0sh
Copy link

d0r0sh commented Oct 13, 2022

My use case was:

  1. use only services without other dependencies (if it make sense for your logic)

It was the responsibility of the code calling bsModalService.show to resolve dependencies. It sounds like you want a new feature. You probably should create a separate issue for that.

@rseanhall Is it planned to add such an option to define a modal injector in the future?

@d0r0sh
Copy link

d0r0sh commented Oct 13, 2022

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants