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
๐ 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.
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.
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.
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. : ]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With