In AngularJs we could make a directive attribute required. How do we do that in Angular with @Input? The docs don\'t mention it.
Eg.
@Component({
selec
Check in ngOnInit()
(inputs aren't yet set when the constructor is executed) whether the attribute has a value.
Component({
selector: 'my-dir',
template: '<div></div>'
})
export class MyComponent implements OnInit, OnChanges {
@Input() a:number; // Make this a required attribute. Throw an exception if it doesnt exist
@Input() b:number;
constructor(){
}
ngOnInit() {
this.checkRequiredFields(this.a);
}
ngOnChanges(changes) {
this.checkRequiredFields(this.a);
}
checkRequiredFields(input) {
if(input === null) {
throw new Error("Attribute 'a' is required");
}
}
}
You might also check in ngOnChanges(changes) {...}
if the values wasn't set to null
. See also https://angular.io/docs/ts/latest/api/core/OnChanges-interface.html
Why not use the @angular/forms
library to validate your @Input
s?
The following solution:
@input
value is accessed by the component for the first time)Usage:
export class MyComponent {
@Input() propOne: string;
@Input() propTwo: string;
ngOnInit() {
validateProps<MyComponent>(this, {
propOne: [Validators.required, Validators.pattern('[a-zA-Z ]*')],
propTwo: [Validators.required, Validators.minLength(5), myCustomRule()]
})
}
}
Utility function:
import { FormArray, FormBuilder, ValidatorFn, FormControl } from '@angular/forms';
export function validateProps<T>(cmp: T, ruleset: {[key in keyof T]?: ValidatorFn[]} ) {
const toGroup = {};
Object.keys(ruleset)
.forEach(key => toGroup[key] = new FormControl(cmp[key], ruleset[key]));
const formGroup = new FormBuilder().group(toGroup);
formGroup.updateValueAndValidity();
const validationResult = {};
Object.keys(formGroup.controls)
.filter(key => formGroup.controls[key].errors)
.forEach(key => validationResult[key] = formGroup.controls[key].errors);
if (Object.keys(validationResult).length) {
throw new Error(`Input validation failed:\n ${JSON.stringify(validationResult, null, 2)}`);
}
}
Stackblitz