Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EventEmitter not working in Angular 2

I'm trying to listen to events on a child component from a parent component like described here in the angular 2 docs but the event never makes it to the parent.

I know for sure that the code runs through this line in the child that emits the event:

this.onResultsRecieved.emit(true);

Here is all my code involved:

Parent:

find-page.component.ts

import { Component } from '@angular/core';
import { NavbarComponent } from '../shared/navbar.component';
import { FindFormComponent } from '../find-page/find-form.component';

@Component({
   selector: 'find-page',
   templateUrl: 'app/find-page/find-page.component.html',
   styleUrls: ['app/find-page/find-page.component.css' ],
   directives: [ FindFormComponent ]
})
export class FindPageComponent {
   showResults = false;

     onResultsRecieved(recieved: boolean) {
        if ( recieved ) {
           this.showResults = true;
        }else {
           this.showResults = false;
        }
  }
}

find-page.component.html:

<div id="find-page">
   <find-form></find-form>
</div>
<div (onResultsRecieved)="onResultsRecieved($event)" *ngIf="showResults" id="results-page">
</div>

Child:

find-form.component.ts

import { Component, OnInit, ViewChild, ElementRef, EventEmitter, Output } from '@angular/core';
import {  REACTIVE_FORM_DIRECTIVES,
  FormGroup,
  FormBuilder,
  Validators,
  ControlValueAccessor
} from '@angular/forms';
import { ResultService } from '../services/result.service';
import { Result } from '../result'
import { NumberPickerComponent } from './number-picker.component';
import { DistanceUnitsComponent } from './distance-units.component';
import { MapDemoComponent } from '../shared/map-demo.component';
import { AreaComponent } from './area-picker.component';
import { GoComponent } from '../shared/go.component';
import { HighlightDirective } from '../highlight.directive';

@Component({
  selector: 'find-form',
  templateUrl: 'app/find-page/find-form.component.html',
  styleUrls: ['app/find-page/find-form.component.css'],
  providers: [ResultService],
  directives: [REACTIVE_FORM_DIRECTIVES,
    NumberPickerComponent,
    DistanceUnitsComponent,
    MapDemoComponent,
    AreaComponent,
    GoComponent]
})
export class FindFormComponent implements OnInit {
  findForm: FormGroup;
  submitted: boolean; // keep track on whether form is submitted
  events: any[] = []; // use later to display form changes
  @ViewChild('keywordsInput') keywordsInput;
  @Output() onResultsRecieved = new EventEmitter<boolean>();
  results: Result[];

  constructor(private resultService: ResultService,
    private formBuilder: FormBuilder,
    el: ElementRef) { }


  goClicked(): void {
    this.getResults();

  }

  getResults(): void {
    this.results = this.resultService.getResults();
    console.log(this.results);
    this.onResultsRecieved.emit(true);
  }

  ngOnInit() {
    this.findForm = this.formBuilder.group({
      firstname: ['', [Validators.required, Validators.minLength(5)]],
      lastname: ['', Validators.required],
      keywords: [],
      area: ['', Validators.required],
      address: this.formBuilder.group({
        street: [],
        zip: [],
        city: []
      })
    });
    this.findForm.valueChanges.subscribe(data => console.log('form changes', data));
  }

  focusKeywordsInput() {
    this.keywordsInput.nativeElement.focus();
  }

  save(isValid: boolean) {
    this.submitted = true;
    console.log(isValid);
    console.log(this.findForm);
  }
}

Why does the event not trigger the onResultsRecieved() function of the parent to execute?

Please note that this Stack Overflow answer includes events : ['update'] on the component but I don't know what that is because it is not in the angular component interaction docs

like image 452
BeniaminoBaggins Avatar asked Aug 27 '16 04:08

BeniaminoBaggins


People also ask

How EventEmitter works in Angular?

๐ŸŽŠ Event Emitters in Angular ๐ŸŽŠData flows into your component via property bindings and flows out of your component through event bindings. If you want your component to notify his parent about something you can use the Output decorator with EventEmitter to create a custom event.

How@ input works in Angular?

Use the @Input() decorator in a child component or directive to let Angular know that a property in that component can receive its value from its parent component. It helps to remember that the data flow is from the perspective of the child component.

What is emit() in Angular?

Use in components with the @Output directive to emit custom events synchronously or asynchronously, and register handlers for those events by subscribing to an instance.


1 Answers

In find-page.component.html, you have the event binded to a regular div element. You need to bind the event to the find-form component because it is what actually contains the EventEmitter you want to receive events from.

<find-form (onResultsReceived)="onResultsReceived($event)"></find-form>

If you copy & paste that in, keep in mind you've also been spelling 'receive' wrong. : ]

like image 153
ABabin Avatar answered Sep 21 '22 02:09

ABabin