Meenal
Meenal

Reputation: 153

How to post value in the nested json array in angular 5?

I have nested json format being exposed from Web API. Can someone help me in sending the same format data from Angular5

{"contractId":1,
 "contractName":"Temp",
 "contractServiceList":[
    {"id":1,
     "serviceId":{"serviceId":1,"serviceName":"Emergency Room"},
     "providerTier":"Tier 1",
     "coinsurance":100.0,
     "copay":10.0,
     "penaltyApplies":"Y",
     "penaltyRule":"Non Emergency ER Use",
     "penaltyType":"Dollar Amount",
     "penaltyValue":300.0,
     "deductibleApplies":"Y"
    }
  ]
}

Below is the piece of code, which gives the inner list "contractServiceList" as null. How to subscribe data so that it should get the values inside the inner list

app.component.ts

ngOnInit() {
    this.addForm = this.formBuilder.group({
          contractName: ['', Validators.required],
          serviceName: ['', Validators.required],
          copayAmount: ['', Validators.required],
          coInsurance: ['', Validators.required],
          deductibleApplies: ['', Validators.required],
          penaltyApplies: ['', Validators.required],
          penaltyRule: ['', Validators.required],
          penaltyType: ['', Validators.required],
          penaltyValue: ['', Validators.required],
          deductibleAppliesPenalty: ['', Validators.required]
    });
}
onSubmit() {
    this.contractService.saveContract(this.addForm.value)
    .subscribe( data => {
        alert('Contract created successfully');
        console.log(data);
    });
}

service.ts

 saveContract(contract: Contract) {
    return this.http.post(this.baseUrl, contract).pipe(map(res => res.json));
  }

app.component.html

<form [formGroup]="addForm" (ngSubmit)="onSubmit()">
  <table>
<thead></thead>
<tbody>
<tr>
   <td>
   <div class="form-group col-xs-6">
      <label for="contractName">Contract Name:</label>
      <input formControlName="contractName" placeholder="Contract Name" class="form-control" name="contractName" id="contractName">
    </div>
   </td>
<td>
 <div class="form-group col-xs-6">
     <h4 style="margin-left:100px;">Penalty Conditions</h4>
    </div>
</td>
</tr>
<tr>
     <td>
    <div class="form-group col-xs-6">
      <label for="serviceName">Category Of Services:</label>
      <select id ="serviceName" formControlName="serviceName" name="serviceName" class="form-control">
    <option *ngFor="let serv of serviceId" [value]="serv.serviceId">{{serv.serviceName}}</option>
</select>
      </div>
    </td>
<td>
 <div class="form-group col-xs-6">
      <label for="penaltyApplies">Penalty Applies:</label>
       <select id ="penaltyApplies" formControlName="penaltyApplies" name="penaltyApplies" class="form-control">
    <option>--Select--</option>
    <option>Y</option>
    <option>N</option>
</select>
</div>
</td>
</tr>
<tr>
    <td>
    <div class="form-group col-xs-6">
      <label for="copayAmount">Copay Amount:</label>
      <input formControlName="copayAmount" placeholder="Copay Amount" class="form-control" name="copayAmount" id="copayAmount">
    </div>
    </td>
    <td>
    <div class="form-group col-xs-6">
      <label for="penaltyRule">Penalty Rule:</label>
       <select id ="penaltyRule" formControlName="penaltyRule" name="penaltyRule" class="form-control">
    <option>--Select--</option>
    <option>Non Emergency ER Use</option>
</select>
      </div>
    </td>
    </tr>
<tr>
    <td>
    <div class="form-group col-xs-6">
      <label for="deductibleApplies">Deductible Applies:</label>
        <select id ="deductibleApplies" formControlName="deductibleApplies" name="deductibleApplies" class="form-control">
    <option>--Select--</option>
    <option>Y</option>
    <option>N</option>
</select></div>
    </td>
    <td>
    <div class="form-group col-xs-6">
      <label for="penaltyType">Penalty Type:</label>
      <select id ="penaltyType" name="penaltyType" formControlName="penaltyType" class="form-control">
    <option>--Select--</option>
    <option>Coinsurance</option>
    <option>Dollar Amount</option>
</select></div>
    </td>
    </tr>

Upvotes: 1

Views: 2039

Answers (1)

Eliseo
Eliseo

Reputation: 57939

Meenal, ContractServiceList is an Array, so you must use an ArrayForm. I suggested always make a function to return a form

export class TabGroupBasicExample implements OnInit {
  addForm:FormGroup;

  //this function make easier access to the Form array
  get contractList() {
     return this.addForm.get('contractServiceList') as FormArray;
  }
  constructor(private formBuilder:FormBuilder){}

  //this function return a FormGroup empty or filled with the data
  createForm(data:any):FormGroup
  {
    return this.formBuilder.group({
      contractId: [data? data.contractId:'',Validators.required],
      serviceName: [data? data.serviceName:''], 
      //to return the array we use a function that return an array of FormGroup
      contractServiceList:this.formBuilder.array(
             this.createContractService(data?data.contractServiceList:null)
              )
      });
  }

  //see that createContractService return an array of FormGroup
  createContractService(data:any[]|null):FormGroup[]
  {
        //if receive a data array, for each item in array return 
        //a fromGroup with the value    
    return data?
      data.map(x=>{
        let group=this.formBuilder.group({
          copayAmount: [x.copayAmount, Validators.required],
          coInsurance: [x.coInsurance, Validators.required],
          deductibleApplies: [x.deductibleApplies, Validators.required],
          penaltyApplies: [x.penaltyApplies, Validators.required],
          penaltyRule: [x.penaltyRule, Validators.required],
          penaltyType: [x.penaltyType, Validators.required],
          penaltyValue: [x.penaltyValue, Validators.required],
          deductibleAppliesPenalty: [x.deductibleAppliesPenalty, Validators.required]
            });
        return group;
      }):
      [this.formBuilder.group(
        {
          copayAmount: ['', Validators.required],
          coInsurance: ['', Validators.required],
          deductibleApplies: ['', Validators.required],
          penaltyApplies: ['', Validators.required],
          penaltyRule: ['', Validators.required],
          penaltyType: ['', Validators.required],
          penaltyValue: ['', Validators.required],
          deductibleAppliesPenalty: ['', Validators.required]
        })]
  }


  ngOnInit()
  {
    this.addForm=this.createForm(null)
    }
}

Update If you has an object like

let contrat={
  "contractId": "2",
  "serviceName": "qqqq",
  "contractServiceList": [
    {
      "copayAmount": "12",
      "coInsurance": "22553",
      "deductibleApplies": "12",
      "penaltyApplies": "",
      "penaltyRule": "",
      "penaltyType": "1",
      "penaltyValue": "",
      "deductibleAppliesPenalty": "2"
    }
  ]
}

You can make

this.addForm=this.createForm(contract)

And you get the values ready for update.

You .html must take account you're working with a formArray

    <form *ngIf="addForm" [formGroup]="addForm" >
      <!--or your fileds not in array-->
       <input formControlName="contractId"/>
       <input formControlName="serviceName">
      <!--Your form Array name---->
    <div formArrayName="contractServiceList">
    <!--a div *ngFor over addForm.get('contractServiceList').controls 
     don't forget formGroupName="i"-->
    <div *ngFor="let items of contractList.controls; let i=index" 
            [formGroupName]="i">

         <!--al your controls of the array here-->
       <input formControlName="copayAmount"/>
       <input formControlName="coInsurance"/>
       ....
    </div>
</div>
<!--just for check -->
<pre>{{addForm?.value |json}}</pre>

Well you want to make a table, Change the .html

Update 2 If we want to validate the formArray itself we can build a custom validator. Well I like make a custom validator as a function in the own component. For Custom validators more generally -user in several component- see https://angular.io/guide/form-validation#custom-validators

So, we can add in the component.ts

   arrayValidator(){

    return (control: FormArray) => {
      console.log(control.value);
      //using value, you return an object if error or null
      return null;
    }
  }   

And change when create the array as

  contractServiceList:this.formBuilder.array(
         this.createContractService(data?data.contractServiceList:null),
         this.arrayValidator()
          )

Upvotes: 2

Related Questions