Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular material stepper: Error: Cannot find control with name: 'formArray'

I tried to follow up with the steps on how to setup angular material stepper here: https://material.angular.io/components/stepper/overview

I wanted a simple single form with multiple steps so I created this:

<form [formGroup]="formGroup">
  <mat-horizontal-stepper formArrayName="formArray" linear>
    <mat-step formGroupName="0" [stepControl]="formArray.get([0])">
      <div>
        <button mat-button matStepperNext type="button">Next</button>
      </div>
    </mat-step>
    <mat-step formGroupName="1" [stepControl]="formArray.get([1])">
      <div>
        <button mat-button matStepperPrevious type="button">Back</button>
        <button mat-button matStepperNext type="button">Next</button>
      </div>
    </mat-step>
  </mat-horizontal-stepper>
</form>

I get on my console:

ERROR Error: Cannot find control with name: 'formArray'
    at _throwError (forms.es5.js:1918)
    at setUpFormContainer (forms.es5.js:1891)
    at FormGroupDirective.webpackJsonp.../../../forms/@angular/forms.es5.js.FormGroupDirective.addFormArray (forms.es5.js:4849)
    at FormArrayName.webpackJsonp.../../../forms/@angular/forms.es5.js.FormArrayName.ngOnInit (forms.es5.js:5134)
    at checkAndUpdateDirectiveInline (core.es5.js:10856)
    at checkAndUpdateNodeInline (core.es5.js:12364)
    at checkAndUpdateNode (core.es5.js:12303)
    at debugCheckAndUpdateNode (core.es5.js:13167)
    at debugCheckDirectivesFn (core.es5.js:13108)
    at Object.eval [as updateDirectives] (MystepperComponent.htm

The full source code of my test is here: angular stepper test example on github

I really did my best to follow the documentation, but i don't understand what I need to do to fix it...

like image 484
Jas Avatar asked Oct 11 '17 13:10

Jas


2 Answers

If you want to use a single form with multiple steps you need to implement the formGroup and formArray in your component's typescript. To your problem it seems you have not implemented formArray in your component's typescript file. Modify your code as follows to make it work.

  1. stepper.component.ts should look something like shown below.
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';

@Component({
  selector: 'app-stepper',
  templateUrl: './stepper.component.html',
  styleUrls: ['./stepper.component.css']
})

export class StepperComponent implements OnInit {

  formGroup: FormGroup;
  constructor(private _formBuilder: FormBuilder) { }

  ngOnInit() {
    this.formGroup = this._formBuilder.group({
      formArray: this._formBuilder.array([
        this._formBuilder.group({}),
        this._formBuilder.group({})
      ])
    });
  }
}

The two this._formbuilder.group({}) within the array are for formArray->'0' and formArray->'1'.

  1. Also update your stepper.component.html as shown below.
<form [formGroup]="formGroup">  
  <mat-horizontal-stepper formArrayName="formArray" linear>    
    <mat-step formGroupName="0" [stepControl]="formArray?.get([0])">
      <div>
        <button mat-button matStepperNext type="button">Next</button>
      </div>
    </mat-step>
    <mat-step formGroupName="1" [stepControl]="formArray?.get([1])">
      <div>
        <button mat-button matStepperPrevious type="button">Back</button>
        <button mat-button matStepperNext type="button">Next</button>
      </div>
    </mat-step>
  </mat-horizontal-stepper>
</form>

I have changed formArray.get([0]) to formArray?.get([0]) and formArray.get([1]) to formArray?.get([1]) as formArray is undefined.

  1. Make sure you have all the required dependencies imported in app.module.ts.

You can find the working solution on the given link - https://stackblitz.com/edit/angular-xuofwu

like image 76
Cyborg Avatar answered Oct 18 '22 01:10

Cyborg


Well, your ngOnInit has the formgroup definition like this,

ngOnInit() {
  this.formGroup = this._formBuilder.group({
    firstCtrl: ['', Validators.required]
  });
}

which doesn't have a formArray defined, so when you refer to formArrayName="formArray" in your template the app will expect a formArray control named 'formArray' within your parent formGroup declared as formGroup (in your case, from these 2 assignments:- this.formGroup = ... and <form [formGroup]="formGroup">). That explains the error you got to answer your question. But do you actually need a formArray there depends on what you are trying to accomplish and I don't think it matters as far as your question is concerned.

Also, you don't seem to be using the formControl defined as firstCtrl anywhere in your template. So essentially what you defined in your component as your reactive form (and its controls) doesn't match with what you have in your template except for just the parent formGroup name formGroup.

Hope it helps.

like image 35
amal Avatar answered Oct 18 '22 00:10

amal