I created a form that contains several FormGroup in a FormArray. The user can dynamically generate several FormGroup according to his needs I initiate a FormGroup in the code so that the user does not fall on an empty page
ngOnInit(): void {
this.buildOrderForm();
}
private buildOrderForm() {
this.orderForm = this.formBuilder.group({
message: [''],
orders: this.formBuilder.array([this.createOrder()]) // this line initiates a first FormGroup
});
}
private createOrder(): FormGroup {
return this.formBuilder.group({
produit: ['', Validators.required],
document: ['', Validators.required],
quantite: ['']
});
}
protected addOrder(): void {
this.ordersFormArray.push(this.createOrder());
}
When I perform a unit test on this code that tests the creation of the component instance, I encounter the following error: Error: No value accessor for form control with path: 'orders -> 0 -> produit'
But when I remove the call from the createOrder method in the FormArray like this, the test proceeds correctly and the component instance is created
private buildOrderForm() {
this.orderForm = this.formBuilder.group({
message: [''],
orders: this.formBuilder.array([]) // suppres createOrder()
});
}
Here's the html template:
<form [formGroup]="orderForm" (ngSubmit)="onSendOrders()">
<div class="container">
<h4 class="container__title">{{ 'order.form.message.printout' | translate }}</h4>
<!--Type de produit-->
<div formArrayName="orders" ngDefaultControl>
<div *ngFor="let order of ordersFormArray.controls; let i = index">
<div [formGroupName]="i">
<mat-form-field appearance="fill">
<mat-label>{{
'order.form.field.product' | translate
}}</mat-label>
<mat-select
formControlName="produit"
(selectionChange)="documentsChangeAction($event.value, i)"
>
<mat-option
id="{{ 'label-option' + i }}"
*ngFor="let product of productList"
[value]="product.label"
>
{{ product.label }}
</mat-option>
</mat-select>
</mat-form-field>
............................
</form>
How can I fix this error ? Thanks for help. Here's the complete code on this stackblitz :
EDIT : added full test code
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { FormArray, ReactiveFormsModule } from '@angular/forms';
import {
createComponentFactory,
mockProvider,
Spectator,
} from '@ngneat/spectator/jest';
import { TestHelperModule } from 'src/test/helpers/test-helper.module';
import { OrderFormComponent } from './order-form.component';
import { IDocumentProduct } from '../model/document-product.model';
import { ConfigService } from '@core/services/config.service';
import { OrderService } from '../service/order.service';
import { Observable, of } from 'rxjs';
import { MatInputModule } from '@angular/material/input';
import { MatIconModule } from '@angular/material/icon';
const productList: IDocumentProduct[] = [
{
id: '1',
label: 'Tous',
documents: [
{
id: '3',
label: 'Sticker moto',
qtteMax: 2,
},
{
id: '2',
label: 'Pochette assuré',
qtteMax: 10,
},
{
id: '5',
label: 'Porte vignette',
qtteMax: 20,
},
{
id: '1',
label: 'Carte verte',
qtteMax: 20,
},
{
id: '4',
label: 'Enveloppe T',
qtteMax: 20,
},
],
},
{
id: '2',
label: 'Auto',
documents: [
{
id: '18',
label: "Convention d'assistance AUTO",
qtteMax: 10,
},
{
id: '14',
label: 'Dépliant assuré AUTO',
qtteMax: 10,
},
{
id: '6',
label: 'Dispositions générales AUTO',
qtteMax: 10,
},
],
},
];
describe('OrderFormComponent', () => {
let spectator: Spectator<OrderFormComponent>;
const createComponent = createComponentFactory({
component: OrderFormComponent,
imports: [
ReactiveFormsModule,
TestHelperModule,
MatIconModule,
MatInputModule,
],
mocks: [NavigationService, NotificationService],
providers: [
mockProvider(OrderService, {
getAllProducts: (): Observable<IDocumentProduct[]> =>
of(productList as IDocumentProduct[]),
}),
mockProvider(ContextSessionService, {
activeProfile: (): Observable<IApporteur | IVendeur | null> =>
of({ protocoleSigne: true } as IApporteur),
activeSubtitutionProfile: (): Observable<
IApporteur | IVendeur | null
> => of(null),
}),
mockProvider(ConfigService, {
getValue: jest.fn(() => 'fakeurlwebadelia.com/apporteur'),
}),
],
});
beforeEach(
() =>
(spectator = createComponent({
props: { productList: productList },
}))
);
it('should create', () => {
expect(spectator.component).toBeInstanceOf(OrderFormComponent);
});
});