2
votes

I'm pretty new to Angular and RxJS. I'm trying to listen for a change event on all mat-radio-group elements in a document. I can't understand why using the @HostListener I can catch the event and log it to the console but not using fromEvent

@Directive({selector: "mat-radio-group"})
export class RadioDirective implements AfterViewInit {
  constructor(private element: ElementRef) {}

  @HostListener('change', ['$event'])
  onChange(event){
    console.log(event)
  }

  ngAfterViewInit() {
    fromEvent(this.element.nativeElement, 'change')
      .subscribe(event => console.log(event))
  }
}

I suspect is something related to the ElementRef but I don't really know what I'm missing. I've used fromEvent for others components and didn't have any problem catching events. I would like to mantain fromEvent because is great for manipulating events using .pipe()

EDIT
If I swap the event with click, fromEvent works perfectly

2

2 Answers

1
votes

That is because the operator fromEvent expects a DOM event, so when you use the directive in a mat-radio-group Angular material returns an EventEmitter<MatRadioChange> so the operator does not trigger.

The docs:

@Output() change: EventEmitter Event emitted when the group value changes. Change events are only emitted when the value changes due to user interaction with a radio button (the same behavior as <input type-"radio">).

Using the click event does work because the mat-radio-group does not have any attribute (click).

1
votes

You can use input event instead of change, like that:

@Directive({selector: "mat-radio-group"})
export class RadioDirective implements AfterViewInit {
  constructor(private element: ElementRef) {}

  @HostListener('change', ['$event'])
  onChange(event){
    console.log(event)
  }

  ngAfterViewInit() {
    fromEvent(this.element.nativeElement, 'input')
      .subscribe(event => console.log(event))
  }
}
  • It's better than click event and it's more like change event because it's trigging even at keyboard events et cetera