0

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

1 Answer 1

1

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

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.