Sandeep Nayak
Sandeep Nayak

Reputation: 4757

Dynamically injecting component in Angular

I have a simple component with a button. The action handler for this button is written in component controller (.ts file) and when clicked alerts and logs.

<button (click)="handleClick($event)"></button>

in button.component.ts

handleClick($event) {
  alert('');
}

This component works fine if included in page directly like so :

<app-button></app-button>

Now, I am trying to inject button component dynamically inside a placeholder. I need to do this as I need to inject multiple components to a placeholder dynamically( inside a for loop).

I have gone through the Angular docs. I have also read through a lot of articles on the web. - this , this and many more.

Issue: I am able to inject the component successfully in the placeholder. However, when I click the button, I see that handleClick is not a function error. Why is the button click handler which has been defined in the button controller not being recognized.

Help me find the missing piece.

UPDATE: The issue was that action handlers of that component needs to be public as suggested by @CommercialSuicide in the comments. Thank you for all the answers and comments.

Upvotes: 2

Views: 985

Answers (3)

P.S.
P.S.

Reputation: 16394

Methods of injected component which you're calling, are they public? If they are private, it's expected behavior, they will not be accessible outside the component, just make them public and you will be able to call them from other components. You can learn more about modifiers in DOCS, in "Public, private, and protected modifiers" section.

Upvotes: 1

Debojyoti
Debojyoti

Reputation: 4841

Parent Component HTML

<app-button *ngFor="let item of array(3);let i = index" [data]="i"></app-button>

Parent Component TS

export class AppComponent  {

  array(n) {

    return Array(n)

  }
}

Button Component HTML

<button (click)='handleClick($event)'>A Button</button>

Button Component TS

export class ButtonComponent implements OnInit {

  @Input() data

  constructor() { }

  ngOnInit() {
  }

  handleClick($event) {
    alert("clicked button-"+this.data)
  }
}

Working example in stackblitz.com

Upvotes: 0

tlt
tlt

Reputation: 15291

in your app-button define:

@Output()
buttonClicked:EventEmitter<any> = new EventEmitter();

within app-button, listen for click event on whatever element you need and handle it in some handler:

clickHnadlerInYourAppButton(){
  this.buttonClicked.emit();
}

make instance of your component in parent like you do and subscribe to its @Output(). E.g.:

yourAppButtonComponentInstance.buttonClicked.subscribe(c => console.log('here is your click'));

don't forget to unsubscribe.

Upvotes: 1

Related Questions