Chrillewoodz
Chrillewoodz

Reputation: 28368

Output EventEmitter is always undefined

I've got a component which needs to emit a value but I cannot for the love of god figure out why the @Output() is always undefined when I call it. I have the exact same code in other components and trigger it the same way but it just does not want to work in this case.

Is there anything wrong I'm doing here?

export class DropdownOptionsSingleComponent implements AfterViewInit {
  @Input() current: any;
  @Output('currentChange') onCurrentChange: EventEmitter<any> = new EventEmitter();

  private isOpen: boolean = false;

  constructor(private _globals: GlobalVariablesService, private _elementRef: ElementRef) {
    this.ns = _globals.ns;

    document.addEventListener('click', (e) => {

      // If the clicked element is not the component element or any of its children, close the dropdown
      if (_elementRef.nativeElement !== e.target && !_elementRef.nativeElement.contains(e.target)) {
        this.isOpen = false;
      }
    });
  }

  ngAfterViewInit() {

    let list = this._elementRef.nativeElement.getElementsByClassName(this.ns + '-dos-list')[0];
    let options = list.getElementsByTagName('li');

    for (let option of options) {
      option.addEventListener('click', this.select);
    }
  }

  toggle() {

    if (this.disabled) {
      this.isOpen = false;

      return false;
    }

    this.isOpen = !this.isOpen;
  }

  close() {
    this.isOpen = false;
  }

  select(e) {
    this.current = e.target.getAttribute('data-model');

    // Error saying this.onCurrentChange is undefined...
    this.onCurrentChange.emit(this.current);
  }
}

Upvotes: 3

Views: 4767

Answers (1)

Thierry Templier
Thierry Templier

Reputation: 202306

The reason is that you reference a method so you lose the execution context. Using the following instead:

option.addEventListener('click', (event) => {
  this.select(event);
});

Or the bind method:

option.addEventListener('click', this.select.bind(this));

But there are drawbacks to use the bind method with TypeScript:

Upvotes: 6

Related Questions