I have a simple form that is suppose to display error messages
import { Component, OnInit, Input } from '@angular/core'
import { NgIf } from '@angular/common'
import {REACTIVE_FORM_DIRECTIVES, FormGroup } from '@angular/forms'
@Component(
{
moduleId: module.id,
selector: 'epimss-error-messages',
template: `
<span class="error" *ngIf="errorMessage !== null">{{errorMessage}}</span>`,
styles: [],
directives: [REACTIVE_FORM_DIRECTIVES, NgIf]
})
export class ErrorMessagesComponent implements OnInit {
@Input()
ctrlName: string
constructor(private _form: FormGroup) {
}
ngOnInit() {
}
get errorMessage() {
// Find the control in the Host (Parent) form
let ctrl = this._form.find(this.ctrlName);
console.log('ctrl| ', ctrl)
// for (let propertyName of ctrl.errors) {
// // If control has a error
// if (ctrl.errors.hasOwnProperty(propertyName) && ctrl.touched) {
// // Return the appropriate error message from the Validation Service
// return CustomValidators.getValidatorErrorMessage(propertyName);
// }
// }
return null;
}
}
Usage
<div layout = "column"
layout-align = "start start">
<md-input required
placeholder = "First"
formControlName = "first"></md-input>
<epimss-error-messages ctrlName = "first"></epimss-error-messages>
<md-input placeholder = "Second"
formControlName = "second"></md-input>
<!--<epimss-error-messages ctrlName = "second"></epimss-error-messages>-->
</div>
Once the line
<epimss-error-messages ctrlName = "first"></epimss-error-messages>
is present I get the following console error and the UI fails to display:
EXCEPTION: Error in http://localhost:4200/app/registration/language/language.component.html:44:2 browser_adapter.ts:74 EXCEPTION: Error in http://localhost:4200/app/registration/language/language.component.html:44:2BrowserDomAdapter.logError @ browser_adapter.ts:74BrowserDomAdapter.logGroup @ browser_adapter.ts:85ExceptionHandler.call @ exception_handler.ts:50(anonymous function) @ application_ref.ts:396ZoneDelegate.invoke @ zone.js:323onInvoke @ ng_zone_impl.ts:64ZoneDelegate.invoke @ zone.js:322Zone.run @ zone.js:216NgZoneImpl.runInner @ ng_zone_impl.ts:96NgZone.run @ ng_zone.ts:211ApplicationRef_.run @ application_ref.ts:384ApplicationRef_.bootstrap @ application_ref.ts:408(anonymous function) @ application_ref.ts:150ZoneDelegate.invoke @ zone.js:323onInvoke @ ng_zone_impl.ts:64ZoneDelegate.invoke @ zone.js:322Zone.run @ zone.js:216(anonymous function) @ zone.js:571ZoneDelegate.invokeTask @ zone.js:356onInvokeTask @ ng_zone_impl.ts:53ZoneDelegate.invokeTask @ zone.js:355Zone.runTask @ zone.js:256drainMicroTaskQueue @ zone.js:474ZoneTask.invoke @ zone.js:426 browser_adapter.ts:74 ORIGINAL EXCEPTION: No provider for FormGroup!BrowserDomAdapter.logError @ browser_adapter.ts:74ExceptionHandler.call @ exception_handler.ts:62(anonymous function) @ application_ref.ts:396ZoneDelegate.invoke @ zone.js:323onInvoke @ ng_zone_impl.ts:64ZoneDelegate.invoke @ zone.js:322Zone.run @ zone.js:216NgZoneImpl.runInner @ ng_zone_impl.ts:96NgZone.run @ ng_zone.ts:211ApplicationRef_.run @ application_ref.ts:384ApplicationRef_.bootstrap @ application_ref.ts:408(anonymous function) @ application_ref.ts:150ZoneDelegate.invoke @ zone.js:323onInvoke @ ng_zone_impl.ts:64ZoneDelegate.invoke @ zone.js:322Zone.run @ zone.js:216(anonymous function) @ zone.js:571ZoneDelegate.invokeTask @ zone.js:356onInvokeTask @ ng_zone_impl.ts:53ZoneDelegate.invokeTask @ zone.js:355Zone.runTask @ zone.js:256drainMicroTaskQueue @ zone.js:474ZoneTask.invoke @ zone.js:426 browser_adapter.ts:74 ORIGINAL STACKTRACE:BrowserDomAdapter.logError @ browser_adapter.ts:74ExceptionHandler.call @ exception_handler.ts:66(anonymous function) @ application_ref.ts:396ZoneDelegate.invoke @ zone.js:323onInvoke @ ng_zone_impl.ts:64ZoneDelegate.invoke @ zone.js:322Zone.run @ zone.js:216NgZoneImpl.runInner @ ng_zone_impl.ts:96NgZone.run @ ng_zone.ts:211ApplicationRef_.run @ application_ref.ts:384ApplicationRef_.bootstrap @ application_ref.ts:408(anonymous function) @ application_ref.ts:150ZoneDelegate.invoke @ zone.js:323onInvoke @ ng_zone_impl.ts:64ZoneDelegate.invoke @ zone.js:322Zone.run @ zone.js:216(anonymous function) @ zone.js:571ZoneDelegate.invokeTask @ zone.js:356onInvokeTask @ ng_zone_impl.ts:53ZoneDelegate.invokeTask @ zone.js:355Zone.runTask @ zone.js:256drainMicroTaskQueue @ zone.js:474ZoneTask.invoke @ zone.js:426 browser_adapter.ts:74 Error: DI Exception at NoProviderError.BaseException [as constructor] (exceptions.ts:13) at NoProviderError.AbstractProviderError [as constructor] (reflective_exceptions.ts:51) at new NoProviderError (reflective_exceptions.ts:84) at ReflectiveInjector_._throwOrNull (reflective_injector.ts:839) at ReflectiveInjector_._getByKeyDefault (reflective_injector.ts:868) at ReflectiveInjector_._getByKey (reflective_injector.ts:830) at ReflectiveInjector_.get (reflective_injector.ts:623) at ElementInjector.get (element_injector.ts:15) at ElementInjector.get (element_injector.ts:15) at _View_LanguageComponent0.createInternal (LanguageComponent.template.js:217)BrowserDomAdapter.logError @ browser_adapter.ts:74ExceptionHandler.call @ exception_handler.ts:67(anonymous function) @ application_ref.ts:396ZoneDelegate.invoke @ zone.js:323onInvoke @ ng_zone_impl.ts:64ZoneDelegate.invoke @ zone.js:322Zone.run @ zone.js:216NgZoneImpl.runInner @ ng_zone_impl.ts:96NgZone.run @ ng_zone.ts:211ApplicationRef_.run @ application_ref.ts:384ApplicationRef_.bootstrap @ application_ref.ts:408(anonymous function) @ application_ref.ts:150ZoneDelegate.invoke @ zone.js:323onInvoke @ ng_zone_impl.ts:64ZoneDelegate.invoke @ zone.js:322Zone.run @ zone.js:216(anonymous function) @ zone.js:571ZoneDelegate.invokeTask @ zone.js:356onInvokeTask @ ng_zone_impl.ts:53ZoneDelegate.invokeTask @ zone.js:355Zone.runTask @ zone.js:256drainMicroTaskQueue @ zone.js:474ZoneTask.invoke @ zone.js:426 browser_adapter.ts:74 ERROR CONTEXT:BrowserDomAdapter.logError @ browser_adapter.ts:74ExceptionHandler.call @ exception_handler.ts:71(anonymous function) @ application_ref.ts:396ZoneDelegate.invoke @ zone.js:323onInvoke @ ng_zone_impl.ts:64ZoneDelegate.invoke @ zone.js:322Zone.run @ zone.js:216NgZoneImpl.runInner @ ng_zone_impl.ts:96NgZone.run @ ng_zone.ts:211ApplicationRef_.run @ application_ref.ts:384ApplicationRef_.bootstrap @ application_ref.ts:408(anonymous function) @ application_ref.ts:150ZoneDelegate.invoke @ zone.js:323onInvoke @ ng_zone_impl.ts:64ZoneDelegate.invoke @ zone.js:322Zone.run @ zone.js:216(anonymous function) @ zone.js:571ZoneDelegate.invokeTask @ zone.js:356onInvokeTask @ ng_zone_impl.ts:53ZoneDelegate.invokeTask @ zone.js:355Zone.runTask @ zone.js:256drainMicroTaskQueue @ zone.js:474ZoneTask.invoke @ zone.js:426 browser_adapter.ts:74 DebugContext {_view: _View_LanguageComponent0, _nodeIndex: 30, _tplRow: 44, _tplCol: 2}BrowserDomAdapter.logError @ browser_adapter.ts:74ExceptionHandler.call @ exception_handler.ts:72(anonymous function) @ application_ref.ts:396ZoneDelegate.invoke @ zone.js:323onInvoke @ ng_zone_impl.ts:64ZoneDelegate.invoke @ zone.js:322Zone.run @ zone.js:216NgZoneImpl.runInner @ ng_zone_impl.ts:96NgZone.run @ ng_zone.ts:211ApplicationRef_.run @ application_ref.ts:384ApplicationRef_.bootstrap @ application_ref.ts:408(anonymous function) @ application_ref.ts:150ZoneDelegate.invoke @ zone.js:323onInvoke @ ng_zone_impl.ts:64ZoneDelegate.invoke @ zone.js:322Zone.run @ zone.js:216(anonymous function) @ zone.js:571ZoneDelegate.invokeTask @ zone.js:356onInvokeTask @ ng_zone_impl.ts:53ZoneDelegate.invokeTask @ zone.js:355Zone.runTask @ zone.js:256drainMicroTaskQueue @ zone.js:474ZoneTask.invoke @ zone.js:426 browser_adapter.ts:84 EXCEPTION: Error in http://localhost:4200/app/registration/language/language.component.html:44:2 ...
Removing the last code above and the display is as expected.
Hope someone can help.
Thanks
You don't need to inject FormGroup, just use it as a class and instantiate it directly.
So your constructor should be just
constructor() {
this._form = new FormGroup({
first: new FormControl('value')
})
}
This seems to be working in my case, quite similar to yours:
import { FormGroupDirective, NgControl } from '@angular/forms';
//...
constructor(@Host() private hostFormGroup: FormGroupDirective) {
}
// ...
get errorMessage() {
// Find the control in the Host (Parent) form
const ctrl: NgControl = this.hostFormGroup.directives
.find(dir => dir.name === this.ctrlName);
// ...
}
I'm not sure if there are cleaner ways, but this seems good at the moment.
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