2

Problem summary: Our app requirement has it such that users can 'add products' which results in new fields being generated. html:

   <div formArrayName="products">
     <label>Products *:</label>
     <div *ngFor="let product of products.controls; index as i;">
       <div [formGroupName]="i">
         <div class="form-group row">
<!--...-->

.ts:

  createProduct(): FormGroup {
    return this.formBuilder.group({
      product: [null, Validators.required], // selector (product)
      contractMonth: [null, Validators.required], // selector (months)
      contractYear: [null, Validators.required], // selector (years)
      comment: [null] // text
    });
  }

However, because of recent introductions of new product types, different product types have different field types.

Firstly, the user selects a product from the productList selector. Depending on the type of product chosen, we display the relevant fields only. For example, for vegetables we maybe ask for vegey-ness selection and for fruits, we ask for fruity-ness selection.

How do we do this form of dynamic formGroup controls? Is it possible without huge groups of ngIfs and redundant controls? We had trouble with validators and ngIf previously too.

We are unsure whether the final html should look like this:

<ng-container *ngIf='Type1'>
<!--Type 1 controls->
<!--...-->
<ng-container *ngIf='Type2'>
<!--...-->

or the createProduct() function changes:

  createProduct(): FormGroup {
    return this.formBuilder.group({
      if (productName === 'Type1'){
       product: [null, Validators.required], // selector (product)
       contractMonth: [null, Validators.required], // selector (months)
       contractYear: [null, Validators.required], // selector (years)
       comment: [null] // text
      }
      // or switch statement and onwards
    },{
// ...
    });
  }

Previously, we (green developers) hardcoded when 2 product types were available. But that is now quickly getting out of hand. We would like our coding to be cleaner and not so sphagetti-like. We currently send redundant fields as null. (Instead of just not having those fields).

I apologise if this problem is not well stated. I will edit on demand!

Using massive amounts of *ngIfs. But my coworker is already swamped and confused. He has troubles with validators as well. setValidators, Validators.required and updateValueAndValidity() and all that.

<!--Example of contract selector, of which there can be many, depending on how many times the user clicks the add product button-->
<ng-select [virtualScroll]="true" [items]="productList" bindLabel="productName" [searchFn]="customSearch" formControlName="product">
                  <ng-template ng-option-tmp let-item="item">
                    {{ item.productName }} <br />
                    <small>Exchange: {{ item.exchange }}</small> <br />
                    <small>Contract Code: {{ item.contractCode }} 
                     </small>
                  </ng-template>
                </ng-select>
<!--...-->

Thank you for reading!

georgeawg
  • 48,608
  • 13
  • 72
  • 95

1 Answers1

0

I found what I was looking for! How to use *ngIf else? and NgSwitch etc. (There are also various answers on how nesting NgSwitch in NgFor!)

Thank you! I'll update my page if anything comes up.