TypeError: Cannot read property '_rawValidators' of null after Ng build

Viewed 21835

I am new to angular. I am dynamically rendering some fields into my reactive form. Everything works great when I am using ng serve with a mock request (i.e. rendering happens properly, no error in the console.log). As soon as I build the project with ng build and use a proper backend, I get the error for each field I am rendering dynamically:

main.js:1 ERROR TypeError: Cannot read property '_rawValidators' of null 

I couldn't find any background on this error. I would love to hear your thoughts.

more background

// these fields change with selection
this.datafields = [{
              dfId: 48,
              dfName: "Phone",
              dfType: "text",
              dfOptions: null,
              dfValue: ""
              },
              {
              dfId: 49,
              dfName: "Eval",
              dfType: "select",
              dfOptions: ["","Remote","Live"],
              df_value: "",
              }]

typescript rendering in ngOnInit (tried ngAfterViewInit with no improvement)

dfGroup = new FormGroup({})
...
...

 this.eyeForm = this.formBuilder.group({
      focus: ['', Validators.required],
 datafields: this.formBuilder.array([])
})

...
...

  if (this.datafields != null || this.datafields != undefined) {
  this.datafields.forEach((x:any) => {
          this.dfGroup.setControl(x.dfName, new FormControl(x.dfValue));
        });
  this.getDataFields.push(this.dfGroup);
  }

and HTML looks like the following:

 <div [formGroup]="dfGroup">
   <div class="row pt-2" *ngFor="let field of datafields; let i=index">
      <div class="col-4 d-flex align-items-center 13required">
         {{field.dfName}}&nbsp;
      </div>
      <div class="col-6">
         <mat-form-field *ngIf="field.dfType == 'text'" appearance="outline">
            <input
            matInput
            [type]="field.dfType"
            [formControlName]="field.dfName"
            required
            />
         </mat-form-field>
         <mat-form-field
            *ngIf="field.dfType == 'select'"
            appearance="outline"
            >
            <mat-select [formControlName]="field.dfName" placeholder="">
               <mat-option
               [value]="option"
               *ngFor="let option of field.dfOptions"
               >
               {{ option }}
               </mat-option>
            </mat-select>
         </mat-form-field>
      </div>
   </div>
</div>
6 Answers

I ran in to this situation when I was mocking out my template and typo'd my formControlName attribute.

<mycomponent formControlName="bogusfieldSpelledWrong" ...>

Why Angular showed it as this error likely has something to do with how the component was initializing/changing the form.

it must be about formControlName. check out your form control names in ts file and html file. for nested groups you can use formGroupName, then use formControlName.

this.yourForm = this.fb.group({
    name: [''],
    contact: this.fb.group({
      address: ['']
    }) 
})
<form [formGroup]="yourForm">
  <input type="text" formControlName="name" />
  <div formGroupName="contact">
    <input type="text" formControlName="address" />
  </div>
</form>

This is caused by malforming the form in the view.

It was caused by misordering formArrayName, the loop and formGroupName

The form (controller)

form = <FormGroup>this.fb.group({
    hops: this.fb.array([
        this.fb.group({...}),
        ...
    ])
});

The view (mistake)

<li class="asset" *ngFor="let control of hops.controls; let i = index;">
    <div formArrayName="hops">
        <div [formGroupName]="i">

The view (corrected)

<div formArrayName="hops">
    <li class="asset" *ngFor="let control of hops.controls; let i = index;">
        <div [formGroupName]="i">

I had a similar issue, you need to add an extra div with property [formGroupName]="i",

The final code would be,

<div [formGroup]="dfGroup">
    <div class="row pt-2" *ngFor="let field of datafields; let i=index">
        <div [formGroupName]="i">
            <div class="col-4 d-flex align-items-center 13required">
                {{field.dfName}}&nbsp;
            </div>
            <div class="col-6">
                <mat-form-field *ngIf="field.dfType == 'text'" appearance="outline">
                    <input matInput [type]="field.dfType" [formControlName]="field.dfName" required />
                </mat-form-field>
                <mat-form-field *ngIf="field.dfType == 'select'" appearance="outline">
                    <mat-select [formControlName]="field.dfName" placeholder="">
                        <mat-option [value]="option" *ngFor="let option of field.dfOptions">
                            {{ option }}
                        </mat-option>
                    </mat-select>
                </mat-form-field>
            </div>
        </div>
    </div>
</div>

This is resolved by adding formcontrolname value. Type error gives you null because it didn't find value from your Component.

In your Html file formcontrolname must be the same as FormGroup value.

For example:

<formControlName = 'username'>

this.formGroupName = this.formBuilder.group({
    username: ["", [Validators.required]],
    }) 
})
//html page properties

    formControlName="drugReproductive"

//ts file attributes
   

     this.drugTypeTwo = new FormControl(0);
        this.drugTypeThree = new FormControl(0);
        this.drugTypeFour = new FormControl(0);
        this.drugTypeFive = new FormControl(0);

    this.drugWithCanisterForm = this.fb.group({
          drugAntineoplastic:this.drugAntineoplastic,
          drugNonAntineoplastic:this.drugNonAntineoplastic,
          drugReproductive:this.drugReproductive,
          drugTypeOne:this.drugTypeOne,
          drugTypeTwo:this.drugTypeTwo,
          drugTypeThree:this.drugTypeThree,
          drugTypeFour:this.drugTypeFour,
          drugTypeFive:this.drugTypeFive,
          configuration: this.configuration,
          deviceId:this.deviceId,
          deviceTypeId: this.deviceTypeId,
          isOtcExcluded: this.isOtcExcluded,
          isScheduleExcluded: this.isScheduleExcluded,
          isUnitOfUsageExcluded: this.isUnitOfUsageExcluded,
          unitOfUsageValue: this.unitOfUsageValue,
          canisterQuantity: this.canisterQuantity,
          canisterSize: this.canisterSize,
          searchText: this.searchText,
          scheduleExcludedValue: this.scheduleExcludedValue,
          nioshValue:this.nioshValue,
          superCellNo:this.superCellNo,
          lockingCellNo:this.lockingCellNo,
          superLockingCellNo:this.superLockingCellNo,
          isNioshExcluded:this.isNioshExcluded
        });

In my case this problem arised, because i didn't bind the formControllName attributes in my form object

Related