Ali
Ali

Reputation: 1759

Nested Form | angular 6

i have the following HTML Form:

<form fxLayout="column" [formGroup]="setPaymentForm" autocomplete="off">
<div class="input-row" fxLayout="row">
    <form class="example-form" [formGroup]="setPaymentClientName">
        <mat-form-field class="example-full-width">
        <input matInput placeholder="Client Name" formControlName="clientName" (ngModelChange) ="getSearchedClients()" aria-label="Clients" [matAutocomplete]="auto" [formControl]="paymt_client_ctrl">
        <mat-autocomplete #auto="matAutocomplete">
            <mat-option *ngFor="let client of filteredClients | async" [value]="client.name">
            <span>{{client.name}}</span> |
            <small> phone: {{client.phone}}</small>
            <small> | address: {{client.address}}</small>
            </mat-option>
        </mat-autocomplete>
        </mat-form-field>
        <br>
    </form>
</div>
<div class="input-row" fxLayout="row" fxLayout.lt-md="column" fxLayoutGap="20px" fxLayoutGap.lt-md="0px">
    <mat-form-field class="inputField" fxFlex>
    <input matInput formControlName="payment_amount" placeholder="Payment Amount" type="text">
    </mat-form-field>
</div>
<div class="input-row" fxLayout="row" fxLayout.lt-md="column" fxLayoutGap="20px" fxLayoutGap.lt-md="0px">
    <mat-checkbox[checked]='this.isCash' formControlName="isCash"> Cash</mat-checkbox>
</div>
<div class="modal-footer">
              <button mat-raised-button name="addButton" (click)="submitPayment()" color="primary">Set Payment</button>
            </div>
</form>

there are two forms outer form which is setPaymentForm and inner form i called it setPaymentClientName.

i want to get the data of the both form when submitting, so i made the following function:

submitPayment(){
    this.setPaymentForm = this.fb.group({
      clientName: [this.clientName, Validators.required],
      payment_amount: [this.payment_amount],
      isCash: [this.isCash]
    });

but i am getting the following error once i open the form:

PaymentsComponent.html:23 ERROR Error: formGroup expects a FormGroup instance. Please pass one in.

       Example:


    <div [formGroup]="myGroup">
      <input formControlName="firstName">
    </div>

    In your class:

    this.myGroup = new FormGroup({
       firstName: new FormControl()
    });

i am very new to angular 6, i get used to build my web projects with angularjs which is completely deiiferent than angular6. any help is appreciated.

Upvotes: 1

Views: 2672

Answers (2)

xrobert35
xrobert35

Reputation: 2556

Here is what I think you want to do : you form a form with 3 fields.

  • The first one is an autocomplete from allowing you to search for a client
  • next one is the payement amount for this client
  • then you need to know he is payed cash or not

About the error, she's pretty clear, you added a formGroup in your HTML seem to not reference an instance formGroup when your are loading the page. To simply things a FormGroup is just a description or your form.

Futhermore like people said I don't think you need to have 2 forms, one will be enough

Here is your html (a bit simplified for the exemple) with one form and submit type button.

<form fxLayout="column" [formGroup]="clientPayementForm" (ngSubmit)="submitForm()" autocomplete="off">

  <!-- autocomplete client -->
  <mat-form-field class="example-full-width">
    <input matInput placeholder="Client Name" formControlName="clientName" aria-label="Clients" [matAutocomplete]="auto">
    <mat-autocomplete #auto="matAutocomplete">
      <mat-option *ngFor="let client of filteredClients | async" [value]="client.name">
        <span>{{client.name}}</span> |
        <small> phone: {{client.phone}}</small>
        <small> | address: {{client.address}}</small>
      </mat-option>
    </mat-autocomplete>
  </mat-form-field>

  <!-- payement amount -->
  <mat-form-field class="inputField" fxFlex>
    <input matInput formControlName="payment_amount" placeholder="Payment Amount" type="text">
  </mat-form-field>

  <!-- checkbox -->
  <mat-checkbox [checked]='this.isCash' formControlName="isCash"> Cash </mat-checkbox>

  <div class="modal-footer">
    <button mat-raised-button name="addButton" type="submit" color="primary">Set Payment</button>
  </div>
</form>

In the TS :

export class MyComponent {

 clientAutocompleteControl = new FormControl();
 clientPayementForm : FormGroup;

 constructor(private fb: FormBuilder){
 }

 ngOnInit(){
   // here you initialize the form used by the formGroup
   this.clientPayementForm = this.fb.group({
      clientName: [this.clientName, Validators.required],
      payment_amount: [this.payment_amount],
      isCash: [this.isCash]
    });

    // manage the autocomplete value to make the auto complete component work
    // you should call you getSearchedClients perhaps with a mergeMap pipe from rxjs
    this.clientPayementForm.controls.clientName.statusChanges.subscribe(pipe(debounceTime(500), ...));
 }

 submitForm(){
  if(this.clientPayementForm.valid){
    // your form is valid :)  you can now call you API to save data
  }
 }

}

Hop it can help, tell me if you need more details

Upvotes: 1

Pranay Mishra
Pranay Mishra

Reputation: 112

You can implement nested forms in Angular. Have a look at the below link: https://medium.com/spektrakel-blog/angular2-building-nested-reactive-forms-7978ecd145e4

You need to use formGroups to differentiate & also add multiple buttons to get your auto-complete data.

Upvotes: 0

Related Questions