1

Is it possible to somehow dependency inject components in Angular? I would like to be able to do something similar to what you can do with services e.g.:

my.module.ts:
providers: [
   {
      provide: MyService,
      useClass: CustomService
   }
]

I have tried to use *ngIf="condition" in a wrapper component, but it will then complain about services not being provided for the components I do not wish to use.

Piyush Jain
  • 1,895
  • 3
  • 19
  • 40
Mick
  • 837
  • 8
  • 23

2 Answers2

0

It is fully possible if you have parent-child relationship between the component and injecting component. so if you have the structure like this

@Component( {
    selector:"app-parent",
    template:" <app-child> </app-child>"
 } )
export class ParentComp { ...}

you could inject parent-component inside the child component via dependency injection

@Component({
    selector:"app-child",
     template:"I am child"
 })
export class ChildComponent{
    constructor(private parentComp:ParentComponent){
}
}

Angular DI will now that you are asking for parent component that child component lives in and will inject it for you.

If you want to inject component not parent-child relationship like, so for example you want to inject the sidenav component into the some table component that lives outside the sidenav, it is hardly achiavable (not recommended also), but possible. if you want to do that, you should probably create shared service, that will share the states between these components.

onik
  • 1,579
  • 1
  • 11
  • 19
  • Sorry I should probably have clarified that I want to inject the component into html similar to how you use ngIf, but I don't want to provide services for components set to *ngIf="false" – Mick Jun 15 '20 at 11:03
-1

Sure, you can provide any value (const, function, class) for the particular injection token. You can find some examples with components providing when we are going to make ControlValueAccessor

@Component({
providers: [     
   { 
     provide: NG_VALUE_ACCESSOR, 
     useExisting: forwardRef(() => CustomInputComponent),
     multi: true     
    }   
]
})
export class CustomInputComponent {...}

You can create your own injection token and provide any stuff you want and components also.

/* In tokens.ts */ 
const MY_TOKEN_NAME = new InjectionToken<MyAmazingComponent>('MY_TOKEN_NAME')

/* In module */    
providers: [
  { provide: MY_TOKEN_NAME, useClass: MyAmazingComponent }
]
  • Thanks for the help Vlad. What would it look like in the html file where I would want to replace the component. Would it just be ? – Mick Jun 15 '20 at 10:53
  • oh, sorry, I misunderstood your situation. it would be better for you to get rid of access parent/child by DI. the best practice is organizing this communication with input/output or with some condition stored in service and access not "component.condition" but "service.condition" – Vlad Borsh Jun 15 '20 at 11:24