0

Problem:

I have build a reactive form in angular which is dynamically adding a form field when the user clicks on plus button. This is how my code looks like.

<form [formGroup]="distributionAddForm" (ngSubmit)="onSubmit(distributionAddForm.value)">


    <div class="row">
        <div class="col-lg-10">
            <div formArrayName="stocks">
                <div *ngFor="let item of distributionAddForm.controls.stocks.controls; let stockIndex=index"
                    [formGroupName]="stocks">
                    <span>Product Item {{stockIndex + 1}}</span>
                    <div class="form-group">
                        <label>Stock :</label>
                        <div class="input-group input-group-alternative mb-3">
                            <select class="custom-select" id="stockid" formControlName="stockId">
                                <option value="0">Select Stock Item</option>
                                <option value="1">GOGREEN MEGA 500ml</option>
                                <option value="2">GOGREEN PLUS 500ml</option>
                            </select>
                        </div>
                    </div>
                    <div class="row">
                        <div class="col-lg-10">
                            <div class="form-group">
                                <label>Quantity :</label>
                                <div class="input-group input-group-alternative mb-3">
                                    <div class="input-group-prepend">
                                        <span class="input-group-text"><i class="nc-icon nc-box"></i></span>
                                    </div>
                                    <input class="form-control" placeholder="10" type="text" formControlName="quantity"
                                        required />
                                </div>
                            </div>
                        </div>
                        <div class="col-lg-2">
                            <button type="button" class="btn btn-danger btn-sm" (click)="removeProducts(stockIndex)"><i
                                    class="fas fa-minus-circle"></i></button>
                        </div>
                    </div>
                </div>
            </div>

        </div>
        <div class="col-lg-2">
            <button type="button" class="btn btn-info btn-sm mt-4" (click)="addProducts()"><i
                    class="fas fa-plus-circle"></i></button>
        </div>
    </div>



    <button type="submit" class="btn btn-success" [disabled]="!distributionAddForm.valid">Add</button>

</form>

This is how I have done it in component.ts file.

 constructor(
        private formBuilder: FormBuilder,
    ) {
        this.distributionAddForm = this.formBuilder.group({
            stocks: this.formBuilder.array([this.initStocks()])
        });
    }

    initStocks() {
        return this.formBuilder.group({
            stockId: ['0', Validators.required],
            quantity: ['', Validators.required]
        });
    }


    get AllStockItems(){
        return this.distributionAddForm.get('stocks') as FormArray;
    }

    addProducts() {
        const control = <FormArray>this.distributionAddForm.controls['stocks'];
        control.push(this.initStocks());
    }

    removeProducts(i: number) {
        if(this.AllStockItems.length>1){
            const control = <FormArray>this.distributionAddForm.controls['stocks'];
            control.removeAt(i);
        }

    }

When we consider this piece of code in component.html file.<span>Product Item {{stockIndex + 1}}</span> stockIndex + 1 is showing the number only in the first input field only. It not showing this number on the dynamically added second input sets. Can someone tell me where I have done wrong? Thank you very much.

4
  • Instead of stocks, try setting the formGroupName to stockIndex. Also, could you provide a minimum reproduction in Stackblitz? Commented Apr 26, 2020 at 8:16
  • @julianobrasil changing stocks to stockIndex was worked. Thank you very much Commented Apr 26, 2020 at 9:11
  • @julianobrasil Now I want to show the validation error msg. In normal input field we show validation message like following.` <div *ngIf="!agentEditForm.controls['quantity'].valid && (agentEditForm.controls['quantity'].dirty||agentEditForm.controls['lname'].touched)" class="alert alert-danger">Last Name is Required </div>`. I want to know how can I show this to this quantity input field in dynamically added form input Commented Apr 26, 2020 at 9:20
  • I'll add an answer with both things, with a little demo. Commented Apr 26, 2020 at 12:24

1 Answer 1

1

I'd suggest you do this:

<div *ngFor="let item of distributionAddForm.controls.stocks.controls; let stockIndex=index" 
     [formGroupName]="stockIndex">

About the error message:

<div class="input-group input-group-alternative mb-3">
  <div class="input-group-prepend">
    <span class="input-group-text">
      <i class="nc-icon nc-box"></i>
    </span>
  </div>
  <input class="form-control" placeholder="10" 
         type="text" formControlName="quantity" required>
</div>
<div *ngIf="_showFormArrayError(stockIndex, 'quantity')" 
     class="alert alert-danger">
  Quantity is Required
</div>

And in the typescript class:

/** Notice that formGroupName is an index */
_showFormArrayError(formGroupName: number, controlName: string): boolean {
  const formArray: FormArray = this.agentEditForm.get('stocks') as FormArray;
  const formGroup: FormGroup = formArray && 
      formArray.get(`${formGroupName}`) as FormGroup;
  const formControl: FormControl = formGroup && 
      formGroup.get(controlName) as FormControl;

  return (formControl && !formControl.valid && 
         (formControl.dirty | formControl.touched));
}

Stackblitz demo

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.