Last active
March 30, 2023 09:27
-
-
Save jhades/a8a16ac802db0bdf0e38953fbbaa05dc to your computer and use it in GitHub Desktop.
Angular Form Array: Complete Guide - blog.angular-university.io/angular-form-array/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
form = this.fb.group({ | |
title: ['', { | |
validators: [ | |
Validators.required, | |
Validators.minLength(5), | |
Validators.maxLength(60) | |
], | |
asyncValidators: [courseTitleValidator(this.courses)], | |
updateOn: 'blur' | |
}], | |
releasedAt: [new Date(), Validators.required], | |
category: ['BEGINNER', Validators.required], | |
downloadsAllowed: [false, Validators.requiredTrue], | |
longDescription: ['', [Validators.required, Validators.minLength(3)]] | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Component({ | |
selector: 'form-array-example', | |
templateUrl: 'form-array-example.component.html', | |
styleUrls: ['form-array-example.component.scss'] | |
}) | |
export class FormArrayExampleComponent { | |
form = this.fb.group({ | |
... other form controls ... | |
lessons: this.fb.array([]) | |
}); | |
constructor(private fb:FormBuilder) {} | |
get lessons() { | |
return this.form.controls["lessons"] as FormArray; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<button mat-mini-fab (click)="addLesson()"> | |
<mat-icon class="add-course-btn">add</mat-icon> | |
</button> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
addLesson() { | |
const lessonForm = this.fb.group({ | |
title: ['', Validators.required], | |
level: ['beginner', Validators.required] | |
}); | |
this.lessons.push(lessonForm); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
deleteLesson(lessonIndex: number) { | |
this.lessons.removeAt(lessonIndex); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<h3>Add Course Lessons:</h3> | |
<div class="add-lessons-form" [formGroup]="form"> | |
<ng-container formArrayName="lessons"> | |
<ng-container *ngFor="let lessonForm of lessons.controls; let i = index"> | |
<div class="lesson-form-row" [formGroup]="lessonForm"> | |
<mat-form-field appearance="fill"> | |
<input matInput | |
formControlName="title" | |
placeholder="Lesson title"> | |
</mat-form-field> | |
<mat-form-field appearance="fill"> | |
<mat-select formControlName="level" | |
placeholder="Lesson level"> | |
<mat-option value="beginner">Beginner</mat-option> | |
<mat-option value="intermediate">Intermediate</mat-option> | |
<mat-option value="advanced">Advanced</mat-option> | |
</mat-select> | |
</mat-form-field> | |
<mat-icon class="delete-btn" (click)="deleteLesson(i)"> | |
delete_forever</mat-icon> | |
</div> | |
</ng-container> | |
</ng-container> | |
<button mat-mini-fab (click)="addLesson()"> | |
<mat-icon class="add-course-btn">add</mat-icon> | |
</button> | |
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Component({ | |
selector: 'form-array-example', | |
templateUrl: 'form-array-example.component.html', | |
styleUrls: ['form-array-example.component.scss'] | |
}) | |
export class FormArrayExampleComponent { | |
form = this.fb.group({ | |
... other form controls ... | |
lessons: this.fb.array([]) | |
}); | |
constructor(private fb:FormBuilder) {} | |
get lessons() { | |
return this.form.controls["lessons"] as FormArray; | |
} | |
addLesson() { | |
const lessonForm = this.fb.group({ | |
title: ['', Validators.required], | |
level: ['beginner', Validators.required] | |
}); | |
this.lessons.push(lessonForm); | |
} | |
deleteLesson(lessonIndex: number) { | |
this.lessons.removeAt(lessonIndex); | |
} | |
} |
The error Type 'AbstractControl<any, any>' is missing the following properties from type 'FormGroup<any>'
happens when you have in tsconfig.json:
"angularCompilerOptions": {
"strictTemplates": true
},
Solution with pipe (I couldn't manage to make it work with generic pipe like in https://stackoverflow.com/a/69466380/588759):
import { Pipe, PipeTransform } from '@angular/core';
import { AbstractControl, FormGroup } from '@angular/forms';
/**
* https://stackoverflow.com/a/72517767/588759
* https://stackoverflow.com/a/67059770/588759
*/
@Pipe({
name: 'formGroup',
})
export class FormGroupPipe implements PipeTransform {
transform(value: AbstractControl): FormGroup<(typeof value)['value']> {
return value as FormGroup<(typeof value)['value']>;
}
}
and use as [formGroup]="lessonForm | formGroup"
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I am wondering the same