0

Lets say i have a checkbox and each checkbox has a categoryId. When i check the checkbox i will get the categoryId and each data will be save as a formArray, example at index 0: 1,1:2,2:4,3:[6] . So this is the data i currently get but my question is instead of storing the data at different index number i want to get the result as index 0:["1,3,4,6"] as array of string. I want to store the data only in index 0 in other words i want to store all the checkbox categoryId only in one index as a string. I'll share my code below. This is the code that i used to get the categoryId from checkbox

onChange(categoryId: string[], isChecked: boolean) {
  debugger
  const categoryIdArray = (this.patientReportForm.controls.hubxCategoryId as FormArray);
  if (isChecked) {
    categoryIdArray.push(new FormControl(categoryId)) 
  } else {
    let index = categoryIdArray.controls.findIndex(x => x.value == categoryId)
    categoryIdArray.removeAt(index);
  }
}

This is formcontrol

this.patientReportForm = this.formBuilder.group({
      patientId : new FormControl(Number(this.clientId)),
      hubxCategoryId : this.formBuilder.array([]),
      notes : new FormControl(),
    })

this is my html section for checkbox

 <div *ngFor="let hubxReport of hubxReportList; let i=index">
                <div class="lineheader  "> 
                  <section class="" [formGroup]="patientReportForm">
                    <p><mat-checkbox color="primary" (change)="onChange(hubxReport.categoryId, $event.checked)">{{hubxReport.categoryName}}</mat-checkbox></p>
                  </section>
                </div>

this is the data i currently get current result

and this is the result i want to get expected result

my final result here patientid is null. Below i'm assigning patientid : this.clientid. when i debug and i check it, this.clientid carries a value 40.But when i submit patientid shows null

patientReportForm=this.getGroup({patientId : this.clientId ,hubxCategoryId:"",notes:""})

result

here this.clientid carries value 40. debug image

2

2 Answers 2

2
  convertValue(){
    const values = this.form.get('hubxCategoryId').value;

    //values is an array [true,true,false,...]
    return this.hubxReport
            //filter gets [{hubxCategoryId:2,categoryName:".."},
            //             {hubxCategoryId:6,categoryName:".."},..]
           .filter((x, index) => values[index]) 

            //maps return only the "Id" [2,6,...]
           .map(x=>x.hubxCategoryId)
           
            //join return an string "2,6,..."
           .join(",")
  }

But take a look to this SO, you not create a FormArray else a FormControl that store an array

Update step by step

Imagine you has

hubxReportList=[{hubxCategoryId:1,categoryName:'Marka'}, 
                 {hubxCategoryId:2,categoryName:'Kilometraza'},
                 {hubxCategoryId:3,categoryName:'Alu felne'}]

You can to have a function like

  getGroup(data:any=null)
  {
    data=data || {patienID:0,hubxCategoryId :"",notes:""}
  
    const list=data.hubxCategoryId?data.hubxCategoryId.split(',').map(x=>+x):[]
    return new FormGroup({
      patienID:new FormControl<number>(data.patienID),
      hubxCategoryId :new FormArray(this.hubxReportList.map(x=>new FormControl(list.indexOf(x.hubxCategoryId)>0))),
      notes:new FormControl<string>(data.notes)
    }) 
  }

//and use 
patientReportForm2=this.getGroup(
             {patienID:0,hubxCategoryId:"1,3",notes:""})
//or 
patientReportForm2=this.getGroup()

As always we have a FormArray we use a getter

  get hubxCategoryIdArray()
  {
    return this.patientReportForm2.get('hubxCategoryId') as FormArray
  }

And the .html

<form [formGroup]="patientReportForm" (submit)="submit(patientReportForm)">
  <div class="lineheader" formArrayName="hubxCategoryId">
    <section
      class=""
      *ngFor="let control of hubxCategoryIdArray.controls; let i = index"
    >
      <p>
        <input type="checkbox" color="primary" [formControlName]="i" />
        {{ hubxReportList[i].categoryName }}
      </p>
    </section>
  </div>
  <button>submit</button>
</form>

The function submit like

  submit(form:FormGroup)
  {
    if (form.valid)
    {
      const data:any={...form.value};
      data.hubxCategoryId=this.hubxReportList
           .filter((x, index) => form.value.hubxCategoryId[index]) 
           .map(x=>x.hubxCategoryId)
           .join(",")

      console.log(data)
    }
  }

Another option is really use a FormControl, not a FormArray that store an string separated by commas

  getGroup(data:any=null)
  {
    data=data || {patienID:0,hubxCategoryId :"",notes:""}
  
    return new FormGroup({
      patienID:new FormControl(data.patienID),
      hubxCategoryId :new FormControl(data.hubxCategoryId ),
      notes:new FormControl(data.notes)
    })
  }

We use ngModel inside a FormGroup

<div *ngFor="let hubxReport of hubxReportList; let i = index">
  <div class="lineheader">
    <section class="">
      <p>
        <input
          type="checkbox"
          color="primary"
          [ngModel]="
            (patientReportForm.get('hubxCategoryId')?.value || [])
                .split(',').indexOf(
                    '' + hubxReport.hubxCategoryId
                 ) >= 0
             "
          (ngModelChange)="onChange(hubxReport.hubxCategoryId, $event)"
          [ngModelOptions]="{ standalone: true }"
        />
        {{ hubxReport.categoryName }}
      </p>
    </section>
  </div>
</div>

And the function onChange

 onChange(categoryId:any,checked:boolean)
  {
     let newValue:string
     const oldValue:string=this.patientReportForm.get('hubxCategoryId').value
     const oldArray=oldValue?oldValue.split(',').map(x=>+x):[] 
     if (checked)
     newValue=this.hubxReportList
              .filter((x) =>  x.hubxCategoryId==categoryId || oldArray.indexOf(x.hubxCategoryId)>=0) 
              .map(x=>x.hubxCategoryId)
              .join(",")     
  
      else
      newValue=this.hubxReportList
              .filter((x) =>  x.hubxCategoryId!=categoryId && oldArray.indexOf(x.hubxCategoryId)>=0) 
              .map(x=>x.hubxCategoryId)
              .join(",")     
  
              console.log(oldArray,newValue)

        this.patientReportForm.get('hubxCategoryId').setValue(newValue)
  }
  onChange(categoryId:any,checked:boolean)
  {
     let newValue:string
     const oldValue:string=this.patientReportForm.get('hubxCategoryId').value
     const oldArray=oldValue?oldValue.split(',').map(x=>+x):[] 
     if (checked)
     newValue=this.hubxReportList
              .filter((x) =>  x.hubxCategoryId==categoryId || oldArray.find(y=>y==x.hubxCategoryId)) 
              .map(x=>x.hubxCategoryId)
              .join(",")     
  
      else
      newValue=this.hubxReportList
              .filter((x) =>  x.hubxCategoryId!=categoryId && oldArray.find(y=>y==x.hubxCategoryId)) 
              .map(x=>x.hubxCategoryId)
              .join(",")     
  
        this.patientReportForm.get('hubxCategoryId').setValue(newValue)
  }

In this case we needn't make anything in submit

You can see in the stackblitz both case

BONUS: we can create a custom form control like the link I indicate, in this stackblitz is improve the code to mannage an string separated by commas

Sign up to request clarification or add additional context in comments.

13 Comments

thanks for the effort, can you help me with a stackblitz code
@user16780164, I update the answer (sorry for the delay)
thanks a lot for the help. this is what i expected. but there is one problem i have categoryId 11,1,2,27,4,6,28 and so on. When i check first checkbox automatically it check two checkbox that is (categoryId 11 and 1)and when i check the third checkbox it works fine(only check one checkbox) but again when i check 4th checkbox it again check two checkbox automatically. What might be the issue
you're going to kill me :( (patientReportForm.get('hubxCategoryId')?.value || '').split(',')
myform=this.getGroup({patientId : this.clientId ,hubxCategoryId:"",notes:""}) . I have given this code still patientid carries null data. I added an image of the result above and i have also added the image for this.clientid data that i see while debugging.Please check the at the above
|
0

Try this: let desiredFormat= this.patientReportForm.value.hubxCategoryId.join(",")

1 Comment

how can i call desiredFormat here hubxCategoryId : this.formBuilder.array([]) , currently data is showing from this line of code if (isChecked) { categoryIdArray.push(new FormControl(categoryId)) }

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.