0

I have a form with next format:

  this.form = this.formBuilder.group({
      title: new FormControl('', [Validators.required, Validators.maxLength(25)]),
      description: new FormControl('', [Validators.maxLength(45)]),
      event: new FormControl('', [Validators.required]),
      properties: this.formBuilder.array([])
    });

Properties array is dynamic and values always depend on selected event. This array can have at least 3 values and max 50 values. Each event has an unique name. That's why I fill this array after event has been selected with the next way:

 getValuesOfPoperty = function (prop) {
    this.selectedEventProperties = [];
    this.propertyService.getValuesOfPoperty(prop.propertyId)
      .subscribe(res => {
        this.selectedEventProperties.push({
          required: prop.required,
          name: prop.name,
          value: prop.defaultValue,
          type: res.name,
          items: res.items
        });
      })

  };

createItem(prop): FormGroup {
    return this.formBuilder.group({
      [prop.name]: prop.value
    });
  }

selectedEvent(type) {
   const temp = this.form.get('properties') as FormArray;

   type.properties.forEach(item => {
     temp.push(this.createItem(item));
     this.getValuesOfPoperty(item)
   });

   console.log(this.form.value)
 }

Console shows me appropriate form object with correct nested properties array like this:

{
 title: '',
 description: '',
 event: 'auth',
 properties: [{ Date: null},
              { Login: null},
              { Result: null}]
}

But at the meantime I get an error in console about every nested object:

Cannot find control with path: 'properties -> Date'

Cannot find control with path: 'properties -> Login'

Cannot find control with path: 'properties -> Result'

This is my HTML

  <form [formGroup]="form" novalidate autocomplete="off">

  <mat-form-field class="form-full-width">
                <mat-select placeholder="event"
                            required
                            formControlName="event">
                  <mat-option *ngFor="let type of events"
                              (click)="selectedEvent(type)"
                              [value]="type.name">
                    {{ type.name }}
                  </mat-option>
                </mat-select>
              </mat-form-field>

              <mat-form-field class="form-full-width">
                <input matInput
                       required
                       formControlName="title"
                       placeholder="title">
              </mat-form-field>

              <mat-form-field class="form-full-width">
                <input matInput
                       formControlName="description"
                       placeholder="description">
              </mat-form-field>

              <div *ngFor="let prop of selectedEventProperties" formArrayName="properties">

                <!-- SELECTS -->
                <mat-form-field class="form-full-width">
                  <mat-select required="{{prop.required}}"
                              formControlName="{{prop.name}}"
                              placeholder="{{prop.name}}">
                    <mat-option *ngFor="let item of prop.items"
                                [value]="prop.value">
                      {{ item.value }}
                    </mat-option>
                  </mat-select>
                </mat-form-field>
              </div>

</form

I appreciate if somebody could help me to figure out where my mistake is or could tell me what I'm doing wrong

Thanks in advance.

1 Answer 1

1

So the problem was in creation dynamic array to display selected event properties, cause I used service, html rendered before the actual data has been received, this is how I solved this problem

 getValuesOfPoperty = function (prop, temp) {
    this.selectedEventProperties = [];
    this.propertyService.getValuesOfPoperty(prop.propertyId)
      .subscribe(res => {
        // add property to dynamic array when the data has been received
        temp.push(this.createItem(prop));
        // work with an array for event properties
        this.selectedEventProperties.push({
          required: prop.required,
          name: prop.name,
          value: prop.defaultValue,
          type: res.name,
          items: res.items
        });
      })

  };

createItem(prop): FormGroup {
    return this.formBuilder.group({
      [prop.name]: prop.value
    });
  }

selectedEvent(type) {
   const temp = this.form.get('properties') as FormArray;

   type.properties.forEach(item => {
     this.getValuesOfPoperty(item, temp)
   });

   console.log(this.form.value)
 }
Sign up to request clarification or add additional context in comments.

1 Comment

@yurzui your modifications are still required

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.