最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Patch the values in angular form - Stack Overflow

programmeradmin1浏览0评论

I am making an application using angular 6, where i am using angular dynamic form.

As of creating the form and submitting i have pleted everything, You could able to see the working stackblitz,

FYI: This form has children elemts which will gets opened and also gets append on click the add button and removes one by last on click the remove button..

The thing i am in the need is, i just need to patch the values to each inputs via service during edit of each row respectively..

Say i call the get service as,

    this.dynamicFormService.getRest(url,token).subscribe(res => {
        this.form.value = res.data;   //Tried this line but got error (Cannot assign to 'value' because it is a constant or a read-only property)
     })

I am trying to patch the values to the form which you can see in dynamic-form.ts in stacblitz,

  ngOnInit() {
    this.form = this.qcs.toFormGroup(this.questions);
}

If i console the the form as console.log(this.form.value), it gives the result as,

template_desc: ""
template_name: ""
template_properties: Array(0)
length: 0
__proto__: Array(0)

And console.log(res.data) in get service result gives,

data:
template_obj_id: "123"
template_desc: "New template description"
template_name: "New Template"
template_properties: Array(1)
0:
property_name: "Property name"
property_origin: ["VBM"]
property_required: true
property_type: "Property type"

I just need to bind this data that es from res.data to get patched to all the form inputs.

These are the values i need to patch to all the inputs respectively like template_name has the value as New Template and template_desc as New template description etc..

And also an another important thing for template_properties value which is array will get open on click add button during create but whereas during edit it should get opened automatically with number of rows present inside template_properties..

Though the question went little bigger for explanation, the thing i am in the need is single.. I need to patch the data es from service (res.data) to each form elements respectively and all the form elements including template_properties needs to be visible in which user can edit and submit the form.

The screenshot of res.data,

Tried with the below answer,

 this.form.patchValue({
      template_desc: res.data.template_desc,
      template_name:  res.data.template_name,
    });

But if i give template_properties: res.data.template_properties, the template properties not getting binded but other two template name and desc getting binded..

Kindly help to achieve the patching of data to the form elements...

I am making an application using angular 6, where i am using angular dynamic form.

As of creating the form and submitting i have pleted everything, You could able to see the working stackblitz, https://stackblitz./edit/angular-x4a5b6-hne6fg

FYI: This form has children elemts which will gets opened and also gets append on click the add button and removes one by last on click the remove button..

The thing i am in the need is, i just need to patch the values to each inputs via service during edit of each row respectively..

Say i call the get service as,

    this.dynamicFormService.getRest(url,token).subscribe(res => {
        this.form.value = res.data;   //Tried this line but got error (Cannot assign to 'value' because it is a constant or a read-only property)
     })

I am trying to patch the values to the form which you can see in dynamic-form.ts in stacblitz,

  ngOnInit() {
    this.form = this.qcs.toFormGroup(this.questions);
}

If i console the the form as console.log(this.form.value), it gives the result as,

template_desc: ""
template_name: ""
template_properties: Array(0)
length: 0
__proto__: Array(0)

And console.log(res.data) in get service result gives,

data:
template_obj_id: "123"
template_desc: "New template description"
template_name: "New Template"
template_properties: Array(1)
0:
property_name: "Property name"
property_origin: ["VBM"]
property_required: true
property_type: "Property type"

I just need to bind this data that es from res.data to get patched to all the form inputs.

These are the values i need to patch to all the inputs respectively like template_name has the value as New Template and template_desc as New template description etc..

And also an another important thing for template_properties value which is array will get open on click add button during create but whereas during edit it should get opened automatically with number of rows present inside template_properties..

Though the question went little bigger for explanation, the thing i am in the need is single.. I need to patch the data es from service (res.data) to each form elements respectively and all the form elements including template_properties needs to be visible in which user can edit and submit the form.

The screenshot of res.data,

Tried with the below answer,

 this.form.patchValue({
      template_desc: res.data.template_desc,
      template_name:  res.data.template_name,
    });

But if i give template_properties: res.data.template_properties, the template properties not getting binded but other two template name and desc getting binded..

Kindly help to achieve the patching of data to the form elements...

Share Improve this question edited Nov 9, 2018 at 10:29 Maniraj Murugan asked Nov 9, 2018 at 5:39 Maniraj MuruganManiraj Murugan 9,08423 gold badges73 silver badges122 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 4

in https://stackblitz./edit/angular-x4a5b6-xcychx?file=src%2Fapp%2Fdynamic-form.ponent.html, I put as "path the values".

The only thing to take account is that you need add to the form as element as has the array.

  //This function serve to add to the array the elments of the arrays
  //Is the same that we use when add a new line to the Array Form
  addControls(control: string) {
    let question: any = this.questions.find(q => q.key == control);
    let children = question ? question.children : null;
    if (children)
      (this.form.get(control) as FormArray).push(this.qcs.toFormGroup(children))
  }
  this.dynamicFormService.getRest(url,token).subscribe(res => {
        //In res.data you have the data.
        //In res.dat.template_properties you has the array

        //Create the Form
        this.form = this.qcs.toFormGroup(this.questions);
        //Add so element at array as was necesary
        for (let i=0;i<this.data.myArray.length;i++)
        {
            this.addControls('template_properties')
        }
        //Finally use patchValue
        this.form.patchValue(res.data);
    }

Well, your data not corresponding with this.questions and there are a problem with your property_origin (about the problem with as convert propertyOrigin to a series of checkBox, let me some time -I'll updated this anwser more later-)

Updated see stackblitz updated Creating a new Question Type to create a list of checkBox There're a problem with the checkBox. In Angular a checkBox can be have only two values "true" or "false". Until I know, there no effect the attrib value.

So, we can not make something like

<input type="checkbox" value="car" formControlName="checkName">
<input type="checkbox" value="dog" formControlName="checkName">

To get in "checkName" an array ['car','dog'] if you checked the two values.

How we can solutionated this? I think that the better idea is has a formGroup like

<div formGroupName="checkName">
  <input type="checkBox" formControlName="car">
  <input type="checkBox" formControlName="dog">
</div>

So, we'll get some like

   checkName={car:true,dog:false}

Well one work is make a new QuestionType "ListCheckBoxQuestion"

export class ListCheckBoxQuestion extends QuestionBase<string> {
  controlType = 'list-chekbox';
  options: {key: string, value: string}[] = [];

  constructor(options: {} = {}) {
    super(options);
    this.options = options['options'] || [];
  }
}

After we can change the dinamic-formquestion.ponent adding a new switch. See that we create a formGroupName with the question.key, and inside this group we create a formControlName using "options"

<div [formGroupName]="question.key"  *ngSwitchCase="'list-chekbox'" >
  <ng-container *ngFor="let opt of question.options">
  <input type="checkbox"  [formControlName]="opt.key">
                <label >{{opt.value}}</label>
  </ng-container>
</div>

Well, the hard part is wen we create the form (the toFormGroup function of question-control-service

toFormGroup(questions: QuestionBase<any>[]) {
    let group: any = {};

    questions.forEach(question => {
      if (question.controlType=="array") {
         group[question.key]=new FormArray([]);
      }else if (question.controlType=="list-chekbox")
      { //We create a FromGroup using the options
        let controls:any={};
        for (let option of question.options)
             controls[option.key]=new FormControl(false);
        group[question.key]=new FormGroup(controls);
        console.log("*",question);
      }
      else {
       ...
      }
    });
    return new FormGroup(group);
  }

Well there're a job to to that is convert our form.value to data and the data received to form.value.

When we received some like ["car","dog"] we must transform to {car:true,dog:true} and when we have {car:true,dog:false} we must transform to ["car"]. We must use map

Update Take a look to the function toFormGroup of question-control-service. This function is the function that create the form. In the last version we add so many lines to the array as values length. Change this funcion to add a linea if no value is indicated

questions.forEach(question => {
      if (question.controlType == "array") {
        group[question.key] = new FormArray([]);
        if (question.value) {
          if (question.children) {
            //If question.children we must to give "value" to the children
            //So the children has as value, the value given in dataArray
            for (let value of question.value) {
              Object.keys(value).forEach(key => {
                let qu = question.children.find(x => x.key == key)
                if (qu) {
                  qu.value = value[key];
                  qu.controlType = qu.elementType
                }
              })
              group[question.key].push(this.toFormGroup(question.children))
            }
          }
        } //Add this lines to add one line to the array if no 
          //value is indicated
    else {
      if (question.children) {
        question.children.forEach(qu => {
          qu.controlType = qu.elementType

        })
        group[question.key].push(this.toFormGroup(question.children))
      }
    }

Use patchValue to set the data to form

this.dynamicFormService.getRest(url,token).subscribe(res => {
   this.form.patchValue({
      template_desc: res.data.template_desc,
      template_name:  res.data.template_name,
    });
 }
发布评论

评论列表(0)

  1. 暂无评论