Home > other >  Angular Dynamic Reactive Form `Error: Cannot set properties of undefined (setting 'value')
Angular Dynamic Reactive Form `Error: Cannot set properties of undefined (setting 'value')

Time:08-27

In my reusable form component I am getting following error:

Error: Cannot set properties of undefined (setting 'value')

I have created a form with json schema, when user required to update the form from app component, I am trying to update the schema what is sent.

here i am finding 2 errors.

  1. on submit form clears itself
  2. my update is not working

getting above error. aswell initial value not able to editted.

please help me to understand the issue.

If my approach is wrong, please let me know the correct approach to create and handle the schema based form.

thanks in advance.

Live Demo

CodePudding user response:

You can use patchValue to load the values into the form, I didnt get the form clearing issue at all and for refresh I used viewChild and called a reload method to sync the form with the schema.

app.com.ts

import { Component, VERSION, ViewChild } from '@angular/core';
import {
  FormBuilder,
  FormControl,
  FormGroup,
  Validators,
} from '@angular/forms';
import { FormSchema } from './form.schema';
import { SharedForm } from './shared/shared.form';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  @ViewChild('sharedForm') sharedForm: SharedForm;
  name: string;
  details = { name: 'chennai' };
  newFormSchema;
  constructor() {
    this.newFormSchema = FormSchema;
  }

  update() {
    this.details = { name: 'sholing' };
  }

  formSubmited(formValue) {
    const update = formValue;
    console.log('formValue', formValue);
    this.newFormSchema = this.newFormSchema.map((item) => {
      item.value = update[item.name]   new Date();
      return item;
    });
    this.sharedForm.reloadForm();
  }
}

app.com.html

<h1>Original the Form</h1>

<shared-form
  #sharedForm
  [schema]="newFormSchema"
  (userFormOnSubmit)="formSubmited($event)"
></shared-form>

<h1>Update the Form</h1>
<!-- 
<shared-form
  #sharedForm
  [schema]="newFormSchema"
  (userFormOnSubmit)="formSubmited($event)"
></shared-form> -->

{{ newFormSchema | json }}

sharedForm.com.ts

import {
  Component,
  EventEmitter,
  Input,
  OnDestroy,
  OnInit,
  Output,
  VERSION,
} from '@angular/core';
import {
  FormBuilder,
  FormControl,
  FormGroup,
  Validators,
} from '@angular/forms';

import { FormSchema } from '../form.schema';

@Component({
  selector: 'shared-form',
  templateUrl: './shared.form.html',
})
export class SharedForm implements OnInit, OnDestroy {
  @Input() schema = FormSchema;
  @Output() userFormOnSubmit = new EventEmitter();
  userForm: FormGroup;
  constructor(private fb: FormBuilder) {
    this.userForm = this.fb.group({
      name: new FormControl('', [Validators.required]),
      username: new FormControl('', [Validators.required]),
    });
  }

  ngOnInit() {
    this.loadValues();
  }

  loadValues() {
    const updateObj = {};
    this.schema.forEach((data) => {
      updateObj[data.name] = data.value;
    });
    this.userForm.patchValue(updateObj);
  }

  updateForm($event) {
    $event.preventDefault();
    console.log(this.userForm.value);
    this.userFormOnSubmit.emit(this.userForm.value);
  }
  ngOnDestroy() {
    console.log('callss');
  }

  updateValue(controlName) {
    return controlName;
  }

  reloadForm() {
    this.loadValues();
  }

  ngAfterViewInit() {
    // this.schema.forEach((item) => {
    //   if (item.formControl === controlName) {
    //     this.userForm.controls[controlName].setValue(item.value);
    //   }
    // });
  }
}

sharedForm.com.html

<div>
  <form [formGroup]="userForm" (ngSubmit)="updateForm($event)">
    <div *ngFor="let element of schema">
      <label>{{ element.name }}</label>
      <input
        [type]="'element.type'"
        [formControlName]="updateValue(element.formControl)"
      />
    </div>
    <button type="submit">Submit</button>
  </form>
</div>

stackblitz

  • Related