5

Im trying to bind a callback function to a directive, when the event is fired the attribute of the parent component are undefined

app.ts

import {Component} from 'angular2/core';
import {bootstrap} from 'angular2/platform/browser';
import {MyComponent} from './my-component';

@Component({
  selector: 'my-app',
  template: `
  <button (click)="appOnClick('CLICK FROM APP')">BUTTOM OUTSIDE COMPONENT</button>
  <br><br>
  <my-component [onClick]="appOnClick"></my-component>`,
  directives: [MyComponent]
})
export class MyApp { 
  
  public theBoundCallback: Function;
  test:string = "THIS SHOULD HAVE A VALUE";
  
  public ngOnInit(){
    this.theBoundCallback = this.appOnClick.bind(this);
  }
  
  appOnClick(someText){
    
    console.log(someText);
    console.log(this.test);
    
  }
}

bootstrap(MyApp);

my-component.ts

import {Component, Input} from 'angular2/core';

@Component({
  selector: 'my-component',
  template: `<button (click)="onClick('CLICK FROM COMPONENT')">BUTTOM INSIDE COMPONENT</button>`
})
export class MyComponent{

  @Input() onClick: Function;
  
}

That will render two buttons:

BUTTOM OUTSIDE COMPONENT, this calls the appOnClick function direct from the app, when clicked the console shows:
- CLICK FROM APP
- THIS SHOULD HAVE A VALUE

BUTTOM INSIDE COMPONENT, this calls the appOnClick function via the @Input function in the component, when clicked the console shows:
- CLICK FROM APP
- undefined

I've created the example on Plunker

Is that a way to assign this correctly so I can work with my object attributes when the callback is trigger?

2 Answers 2

13

Updated plunkr

In order to pass appOnClick around this way, you need to declare it as a property like so:

export class MyApp {
  ...
  appOnClick = (someText) => {
    console.log(someText);
    console.log(this.test);
  }
} 

instead of:

export class MyApp {
  ...
  appOnClick(someText){
    console.log(someText);
    console.log(this.test);
  }
} 
Sign up to request clarification or add additional context in comments.

2 Comments

@Mush - no problem :-) if this answer solved the problem, please consider accepting it
Thanks for this drewmoore, been banging my head why I couldn't access this.
0

I think that you forgot "(...)" when using the appOnClick method and use "[...]" instead of "(...)" when configuring the event handler:

<my-component (onClick)="appOnClick($event)"></my-component>`,

Moreover within your sub component you need to define a custom event with "@Output":

@Component({
  selector: 'my-component',
  template: `<button (click)="handleClick('CLICK FROM COMPONENT')">BUTTOM INSIDE COMPONENT</button>`
})
export class MyComponent{
  @Output()
  onClick:EventEmitter<string> = new EventEmitter();

  handleClick(txt:string) {
    this.onClick.emit(txt);
  }     
}

Comments

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.