Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 - subscribing to Observable.fromEvent error: "Invalid event target"

I am getting a weird error when trying to subscribe to an Observable.

Here is a watered down version of the code which presents the problem:

import {Component, Input, OnInit, ViewChild} from '@angular/core';
import Rx from 'rxjs/Rx';

@Component({
  selector: 'action-overview-description',
  template: require('./actionOverviewDescription.html')
})
export class ActionOverviewDescription  {
  @ViewChild('button') button;

  constructor() {}
  
   ngOnInit() {

    let buttonStream$ = Rx.Observable.fromEvent(this.button, 'click')
        .subscribe(res => console.log(res));

  }
}
<button #input>Button</button>

The error I get in the console is:

Invalid event target

The error ONLY shows up when I subscribe to the stream. If I only create it but don't subscribe, there is no error. If I console.log the stream it seems to have a subscribe member.

I have tried googling the error but I can't seem to find anywhere it's explained.

I think I'm using Rxjs 4.0.5 (according to npm rxjs --version).

like image 820
deafdigit Avatar asked Feb 25 '17 10:02

deafdigit


2 Answers

The problem is the lifecycle hook you're using. The element is not yet creating in DOM when ngOnInit is called. Instead, you should use ngAfterViewInit.

Could you try the following code:

import { Component, ViewChild, ElementRef, AfterViewInit } from '@angular/core';
import { Observable, fromEvent } from 'rxjs';

@Component({
  template: '<button #input>Button</button>'
})
export class ActionOverviewDescription implements AfterViewInit {
  @ViewChild('input') button: ElementRef;

  ngAfterViewInit() {
    let buttonStream$ = Observable.fromEvent(this.button.nativeElement, 'click')
        .subscribe(res => console.log(res));

  }
}
like image 99
AngularChef Avatar answered Nov 16 '22 10:11

AngularChef


If you want to access it in ngOnInit event then you would have to use { static: true } property of ViewChild something like this:

import { Component, ViewChild, ElementRef, OnInit } from '@angular/core';
import { Observable, fromEvent } from 'rxjs';

@Component({
  template: '<button #input>Button</button>'
})
export class ActionOverviewDescription implements OnInit {
  @ViewChild('input', { static: true }) button: ElementRef;

  ngOnInit() {
    let buttonStream$ = Observable.fromEvent(this.button.nativeElement, 'click')
        .subscribe(res => console.log(res));

  }
}
like image 1
Jameer Khan Avatar answered Nov 16 '22 11:11

Jameer Khan