binding data to angular checkbox2019 Community Moderator ElectionFormArray in Angular - basics understandingCan HTML checkboxes be set to readonly?Event binding on dynamically created elements?Setting “checked” for a checkbox with jQuery?How to check whether a checkbox is checked in jQuery?Check if checkbox is checked with jQueryHow to style a checkbox using CSS?How to create an HTML checkbox with a clickable labelHow does data binding work in AngularJS?Angular HTML bindingCan't bind to 'ngModel' since it isn't a known property of 'input'

Is it possible to avoid unpacking when merging Association?

Conservation of Mass and Energy

Confusion about Complex Continued Fraction

Can I use a violin G string for D?

Why is gluten-free baking possible?

How exactly does an Ethernet collision happen in the cable, since nodes use different circuits for Tx and Rx?

I reported the illegal activity of my boss to his boss. My boss found out. Now I am being punished. What should I do?

Why is a very small peak with larger m/z not considered to be the molecular ion?

Why is there an extra space when I type "ls" in the Desktop directory?

Which situations would cause a company to ground or recall a aircraft series?

What are some noteworthy "mic-drop" moments in math?

What stops an assembly program from crashing the operating system?

Windows Server Datacenter Edition - Unlimited Virtual Machines

Did Amazon pay $0 in taxes last year?

How do we create new idioms and use them in a novel?

Signed and unsigned numbers

Having the player face themselves after the mid-game

Minimizing with differential evolution

Can I negotiate a patent idea for a raise, under French law?

Power Strip for Europe

Does a difference of tense count as a difference of meaning in a minimal pair?

How to write a chaotic neutral protagonist and prevent my readers from thinking they are evil?

Whose blood did Carol Danver's receive, Mar-vell's or Yon-Rogg's in the movie?

Am I understanding this Storm King's Thunder map wrong?



binding data to angular checkbox



2019 Community Moderator ElectionFormArray in Angular - basics understandingCan HTML checkboxes be set to readonly?Event binding on dynamically created elements?Setting “checked” for a checkbox with jQuery?How to check whether a checkbox is checked in jQuery?Check if checkbox is checked with jQueryHow to style a checkbox using CSS?How to create an HTML checkbox with a clickable labelHow does data binding work in AngularJS?Angular HTML bindingCan't bind to 'ngModel' since it isn't a known property of 'input'










1















I managed to bind the data from this.empDetails.services correctly on the UI, checkboxes are checked correctly, and also listed all the checkboxes options.



However, the data are not pushed to the serviceFormArray, when I click update without any changes to the checkbox, this.updateServicesForm.value is empty.



I have to uncheck those checked checkboxes and then check it again so that it will push to the formarray.



I tried a few changes, but to no avail, can someone suggest what is the correct code to archived what I need? Thank you so much.
HTML



<form action="javascript:" [formGroup]="updateSvcForm">
<div class="row" *ngFor="let service of servicesOptions; let i=index">
<div class="col-sm-12">
<div class="checkbox-color checkbox-primary">
<input type="checkbox" id=service.value [value]="service.value" (change)="onCheckChange($event)" [checked]=isSelected(service.value)>
<label for=service.value>
service.description
</label>
</div>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2"></label>
<div class="col-sm-10">
<button class="btn btn-primary m-b-0 ripple light" (click)="updateServices()">Update</button>
</div>
</div>
</form>


Component.TS



sservicesOptions = [
description: '1. Sweeping', value: 'sweeping' ,
description: '2. Mopping', value: 'mopping' ,
description: '3. Windows', value: 'windows' ,
description: '4. Washing Clothes', value: 'washingclothes' ,
];


this.updateSvcForm= this.fb.group(
sservices: new FormArray([]),
);

onCheckChange(event)
const sservicesFormArray: FormArray =
this.updateSvcForm.get('sservices') as FormArray;


if (event.target.checked)
sservicesFormArray.push(new FormControl(event.target.value));

else
let i: number = 0;
sservicesFormArray.controls.forEach((ctrl: FormControl) =>
if (ctrl.value == event.target.value)
sservicesFormArray.removeAt(i);
return;

i++;
);



isSelected(sserviceOption)
return this.empDetails.services.indexOf(serviceOption) >= 0;

console.log(this.updateSvcForm.value);
}


Data from this.empDetails.services API return



sservices: Array(2)
0: "mopping"
1: "washingclothes"
length: 2
__proto__: Array(0)









share|improve this question

















This question has an open bounty worth +50
reputation from Devora ending ending at 2019-03-13 13:46:22Z">in 2 days.


Looking for an answer drawing from credible and/or official sources.
















  • how do you fill this.EmployeeDetails ? can you show more code please

    – Mohamed Ali RACHID
    Mar 4 at 13:33











  • Just a normal api return. The return result is as shown in the last part of the post

    – Devora
    Mar 4 at 13:44











  • can you show how do you get it from the api ? are you using updateServicesForm in HTML ? (is it updateSvcForm ?)

    – Mohamed Ali RACHID
    Mar 4 at 13:50











  • Yes its updateSvcForm. FormGroupName in html

    – Devora
    Mar 4 at 14:07











  • await this.employeeService.getEmployeeDetails(this.Employeeuuid).subscribe((res) =>  
    show 2 more comments










1















I managed to bind the data from this.empDetails.services correctly on the UI, checkboxes are checked correctly, and also listed all the checkboxes options.



However, the data are not pushed to the serviceFormArray, when I click update without any changes to the checkbox, this.updateServicesForm.value is empty.



I have to uncheck those checked checkboxes and then check it again so that it will push to the formarray.



I tried a few changes, but to no avail, can someone suggest what is the correct code to archived what I need? Thank you so much.
HTML



<form action="javascript:" [formGroup]="updateSvcForm">
<div class="row" *ngFor="let service of servicesOptions; let i=index">
<div class="col-sm-12">
<div class="checkbox-color checkbox-primary">
<input type="checkbox" id=service.value [value]="service.value" (change)="onCheckChange($event)" [checked]=isSelected(service.value)>
<label for=service.value>
service.description
</label>
</div>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2"></label>
<div class="col-sm-10">
<button class="btn btn-primary m-b-0 ripple light" (click)="updateServices()">Update</button>
</div>
</div>
</form>


Component.TS



sservicesOptions = [
description: '1. Sweeping', value: 'sweeping' ,
description: '2. Mopping', value: 'mopping' ,
description: '3. Windows', value: 'windows' ,
description: '4. Washing Clothes', value: 'washingclothes' ,
];


this.updateSvcForm= this.fb.group(
sservices: new FormArray([]),
);

onCheckChange(event)
const sservicesFormArray: FormArray =
this.updateSvcForm.get('sservices') as FormArray;


if (event.target.checked)
sservicesFormArray.push(new FormControl(event.target.value));

else
let i: number = 0;
sservicesFormArray.controls.forEach((ctrl: FormControl) =>
if (ctrl.value == event.target.value)
sservicesFormArray.removeAt(i);
return;

i++;
);



isSelected(sserviceOption)
return this.empDetails.services.indexOf(serviceOption) >= 0;

console.log(this.updateSvcForm.value);



Data from this.empDetails.services API return



sservices: Array(2)
0: "mopping"
1: "washingclothes"
length: 2
__proto__: Array(0)









share|improve this question

















This question has an open bounty worth +50
reputation from Devora ending ending at 2019-03-13 13:46:22Z">in 2 days.


Looking for an answer drawing from credible and/or official sources.
















  • how do you fill this.EmployeeDetails ? can you show more code please

    – Mohamed Ali RACHID
    Mar 4 at 13:33











  • Just a normal api return. The return result is as shown in the last part of the post

    – Devora
    Mar 4 at 13:44











  • can you show how do you get it from the api ? are you using updateServicesForm in HTML ? (is it updateSvcForm ?)

    – Mohamed Ali RACHID
    Mar 4 at 13:50











  • Yes its updateSvcForm. FormGroupName in html

    – Devora
    Mar 4 at 14:07











  • await this.employeeService.getEmployeeDetails(this.Employeeuuid).subscribe((res) => this.EmployeeDetails = res as Employee[];

    – Devora
    Mar 4 at 14:07













share|improve this question
















I managed to bind the data from this.empDetails.services correctly on the UI, checkboxes are checked correctly, and also listed all the checkboxes options.



However, the data are not pushed to the serviceFormArray, when I click update without any changes to the checkbox, this.updateServicesForm.value is empty.



I have to uncheck those checked checkboxes and then check it again so that it will push to the formarray.



I tried a few changes, but to no avail, can someone suggest what is the correct code to archived what I need? Thank you so much.
HTML



<form action="javascript:" [formGroup]="updateSvcForm">
<div class="row" *ngFor="let service of servicesOptions; let i=index">
<div class="col-sm-12">
<div class="checkbox-color checkbox-primary">
<input type="checkbox" id=service.value [value]="service.value" (change)="onCheckChange($event)" [checked]=isSelected(service.value)>
<label for=service.value>
service.description
</label>
</div>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2"></label>
<div class="col-sm-10">
<button class="btn btn-primary m-b-0 ripple light" (click)="updateServices()">Update</button>
</div>
</div>
</form>


Component.TS



sservicesOptions = [
description: '1. Sweeping', value: 'sweeping' ,
description: '2. Mopping', value: 'mopping' ,
description: '3. Windows', value: 'windows' ,
description: '4. Washing Clothes', value: 'washingclothes' ,
];


this.updateSvcForm= this.fb.group(
sservices: new FormArray([]),
);

onCheckChange(event)
const sservicesFormArray: FormArray =
this.updateSvcForm.get('sservices') as FormArray;


if (event.target.checked)
sservicesFormArray.push(new FormControl(event.target.value));

else
let i: number = 0;
sservicesFormArray.controls.forEach((ctrl: FormControl) =>
if (ctrl.value == event.target.value)
sservicesFormArray.removeAt(i);
return;

i++;
);



isSelected(sserviceOption)
return this.empDetails.services.indexOf(serviceOption) >= 0;

console.log(this.updateSvcForm.value);
}


Data from this.empDetails.services API return



sservices: Array(2)
0: "mopping"
1: "washingclothes"
length: 2
__proto__: Array(0)






javascript angular typescript checkbox






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 4 at 14:05







Devora

















asked Mar 4 at 13:21









DevoraDevora

5710




5710






This question has an open bounty worth +50
reputation from Devora ending ending at 2019-03-13 13:46:22Z">in 2 days.


Looking for an answer drawing from credible and/or official sources.








This question has an open bounty worth +50
reputation from Devora ending ending at 2019-03-13 13:46:22Z">in 2 days.


Looking for an answer drawing from credible and/or official sources.














  • how do you fill this.EmployeeDetails ? can you show more code please

    – Mohamed Ali RACHID
    Mar 4 at 13:33











  • Just a normal api return. The return result is as shown in the last part of the post

    – Devora
    Mar 4 at 13:44











  • can you show how do you get it from the api ? are you using updateServicesForm in HTML ? (is it updateSvcForm ?)

    – Mohamed Ali RACHID
    Mar 4 at 13:50











  • Yes its updateSvcForm. FormGroupName in html

    – Devora
    Mar 4 at 14:07











  • await this.employeeService.getEmployeeDetails(this.Employeeuuid).subscribe((res) => { this.EmployeeDetails = res as Employee[];

    – Devora
    Mar 4 at 14:07

















  • how do you fill this.EmployeeDetails ? can you show more code please

    – Mohamed Ali RACHID
    Mar 4 at 13:33











  • Just a normal api return. The return result is as shown in the last part of the post

    – Devora
    Mar 4 at 13:44











  • can you show how do you get it from the api ? are you using updateServicesForm in HTML ? (is it updateSvcForm ?)

    – Mohamed Ali RACHID
    Mar 4 at 13:50











  • Yes its updateSvcForm. FormGroupName in html

    – Devora
    Mar 4 at 14:07











  • await this.employeeService.getEmployeeDetails(this.Employeeuuid).subscribe((res) => { this.EmployeeDetails = res as Employee[];

    – Devora
    Mar 4 at 14:07
















how do you fill this.EmployeeDetails ? can you show more code please

– Mohamed Ali RACHID
Mar 4 at 13:33





how do you fill this.EmployeeDetails ? can you show more code please

– Mohamed Ali RACHID
Mar 4 at 13:33













Just a normal api return. The return result is as shown in the last part of the post

– Devora
Mar 4 at 13:44





Just a normal api return. The return result is as shown in the last part of the post

– Devora
Mar 4 at 13:44













can you show how do you get it from the api ? are you using updateServicesForm in HTML ? (is it updateSvcForm ?)

– Mohamed Ali RACHID
Mar 4 at 13:50





can you show how do you get it from the api ? are you using updateServicesForm in HTML ? (is it updateSvcForm ?)

– Mohamed Ali RACHID
Mar 4 at 13:50













Yes its updateSvcForm. FormGroupName in html

– Devora
Mar 4 at 14:07





Yes its updateSvcForm. FormGroupName in html

– Devora
Mar 4 at 14:07













await this.employeeService.getEmployeeDetails(this.Employeeuuid).subscribe((res) => { this.EmployeeDetails = res as Employee[];

– Devora
Mar 4 at 14:07





await this.employeeService.getEmployeeDetails(this.Employeeuuid).subscribe((res) => { this.EmployeeDetails = res as Employee[];

– Devora
Mar 4 at 14:07












3 Answers
3






active

oldest

votes


















0














you forget to set the new value of the form Array sservices :



onCheckChange(event) 
const sservicesFormArray: FormArray =
this.updateSvcForm.get('sservices') as FormArray;


if (event.target.checked)
sservicesFormArray.push(new FormControl(event.target.value));

else
let i: number = 0;
sservicesFormArray.controls.forEach((ctrl: FormControl) =>
if (ctrl.value == event.target.value)
sservicesFormArray.removeAt(i);
break;

i++;
);

// set the new value of sservices form array
this.updateSvcForm.setControl('sservices', sservicesFormArray);






share|improve this answer























  • I will try but i doubt it work. As this is onCheckChange is triggered only if a checkbox is checked manually.

    – Devora
    Mar 5 at 3:56












  • yup its not working. any other solution?

    – Devora
    Mar 5 at 13:55


















0














the "easy" way is to create a FormArray with values true/false. see the example in stackblitz



Update:Correct some errors



You fill the formArray using the data and the sservicesOptions



getFormArrayService(data:any[]):FormArray

//e.g. data=['mopping','washingclothes']
// return a FormArray and the value will be [false,true,false,true]
//if data=null, return a FormArray [false,false,false,false]
return new FormArray(
this.sservicesOptions.map(x=>new FormControl(data?data.find(dat=>dat==x.value)?true:false:false))
)



So, you can, in ngInit make some like



ngOnInit()

this.updateSvcForm=new FormGroup(
sservices:this.getFormArrayService(null)
)



And in submitting the form, transform the value



 submit(updateSvcForm)

if (updateSvcForm.valid)

let services:string[]=[];
updateSvcForm.value.sservices.forEach((x,index)=>

if (x)
services.push(this.sservicesOptions.value)
)
const result=
...updateSvcForm.value, //all value of the form but
sservices:services

console.log(result)




The .html becomes like



<form *ngIf="updateSvcForm" [formGroup]="updateSvcForm" (submit)="submit(updateSvcForm)">
<div formArrayName="sservices">
<div *ngFor="let control of updateSvcForm.get('sservices').controls;let i=index">
<input type="checkbox" [formControlName]="i"/>
sservicesOptions[i].description

</div>
</div>
<button type="submit">submit</button>
</form>
updateSvcForm?.value


The "not so easy way" a customFormControl, see an example in stackblitz



Basically, we create a series of the checkbox, each change in checkbox return the "booleansToProp". In the example, I add a property "required", then indicate it is invalid if no check is checked and isString if we can return a string, not an array



@Component(
selector: 'check-box-group',
template: `
<ng-container *ngFor="let item of source;let i=index;let last=last">

<div [ngClass]="last?'form-group':''" class="form-check" >
<input type="checkbox" class="form-check-input" id="_name+''+i"
[ngModel]="_selectedItems[i]"
(ngModelChange)="setValue($event,i)" (blur)="onTouched()" >
<label class="form-check-label" for="_name+''+i">item[_col]</label>
</div>

</ng-container>
`,
providers: [

provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => CheckBoxGroupComponent),
multi: true
,

provide: NG_VALIDATORS,
useExisting: forwardRef(() => CheckBoxGroupComponent),
multi: true,


],
styles:[`
.focused
outline: black dotted thin;
`
]
)
export class CheckBoxGroupComponent implements ControlValueAccessor null
if (!this._isRequired)
return null;
if (!this._selectedItems.find(x=>x))
return error:"you must select one option at last"

return null


//we received an array (or a string separated by commas) and
//return an array of true/false
propsToBoolean(props): any[]
let propsString=props?props.map(x=>''+x):null;
return props ? this.source.map((x: any) => propsString.indexOf(''+x[this._key]) >= 0)
: this.source.map(x => false);



//we received an array of true/false and return an array with the values
//or with teh values separated by commas
booleanToProps(propsBoolean: boolean[])
let props: any[] = [];
if (propsBoolean)
propsBoolean.forEach((item, index) =>
if (item)
props.push(this.source[index][this._key])
)

return props;









share|improve this answer

























  • where do i call getFormArrayService?

    – Devora
    Mar 7 at 2:23











  • services.push(this.sservicesOptions.value) and where does these value come from?

    – Devora
    Mar 7 at 2:34











  • @Devora, I update my answer and make a stackbliz. I hope this help you

    – Eliseo
    Mar 7 at 8:07


















0














The reason for this, is that you are using checked to mark which checkboxes should be checked, they have no correlation to your form array, so if you do not touch the checkboxes, the formarray will correctly be empty.



I can come up with a couple options to solve this... also the following changes:



change function could be changed to this:



onCheckChange(event) 
if (event.target.checked)
this.ssArray.push(this.fb.control(event.target.value));

else
this.ssArray.removeAt(this.ssArray.value.findIndex(x => x === event.target.value))




Doesn't matter how you do it, your way works as well :) I also like using FormBuilder (here injected as fb).



I like to use a getter in this case:



get ssArray() 
return this.updateSvcForm.get('sservices') as FormArray;



The options I can think of:



  1. add a checked property to the objects in your array sservicesOptions

  2. Keep your isSelected function, but add the chosen options to your formarray initially


I like option 1 best, so add a checked property to the objects:



servicesOptions = [
description: '1. Sweeping', value: 'sweeping', checked: false ,
description: '2. Mopping', value: 'mopping', checked: false ,
description: '3. Windows', value: 'windows', checked: false ,
description: '4. Washing Clothes', value: 'washingclothes', checked: false ,
];


Then when you build the form, change the checked status for those that should be preselected, and also add the values that should be checked to your form array:



constructor(private fb: FormBuilder) 
this.updateSvcForm = this.fb.group(
sservices: this.fb.array([]),
);
// change the checked status for the checkboxes that should be checked
this.servicesOptions.map(x =>
this.empDetails.services.indexOf(x) >= 0 ? x.checked = true : x.checked = false)
// initially set the selected form controls to the formarray
this.empDetails.services.map((x) => this.ssArray.push(this.fb.control(x)))



Then you can add [checked]="service.checked" in template.



DEMO




Option 2:



Keep your checked function like you have, just remember to add the prechosen values to your formarray. I don't really like this option, since for example, we end up calling a function in template, which is really not recommended. But anyway, keep the code as the same as you have now, just add the intial values to the formarray:



this.updateSvcForm = this.fb.group(
sservices: this.fb.array([]),
);
// add the intial values to the formarray:
this.empDetails.services.map((x) => this.ssArray.push(this.fb.control(x)))


DEMO



I added a console.log inside the function, to show how it is called. It's okay for a demo like this, but if you have a big form, I would really caution for you to use this solution.




There would be a third option, to actually set all values to your form array, and then just toggle the boolean value of the checkbox, but that would require some refactoring of code, which I don't know if you want. But there is that option too.






share|improve this answer






















    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54984196%2fbinding-data-to-angular-checkbox%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    you forget to set the new value of the form Array sservices :



    onCheckChange(event) 
    const sservicesFormArray: FormArray =
    this.updateSvcForm.get('sservices') as FormArray;


    if (event.target.checked)
    sservicesFormArray.push(new FormControl(event.target.value));

    else
    let i: number = 0;
    sservicesFormArray.controls.forEach((ctrl: FormControl) =>
    if (ctrl.value == event.target.value)
    sservicesFormArray.removeAt(i);
    break;

    i++;
    );

    // set the new value of sservices form array
    this.updateSvcForm.setControl('sservices', sservicesFormArray);






    share|improve this answer























    • I will try but i doubt it work. As this is onCheckChange is triggered only if a checkbox is checked manually.

      – Devora
      Mar 5 at 3:56












    • yup its not working. any other solution?

      – Devora
      Mar 5 at 13:55















    0














    you forget to set the new value of the form Array sservices :



    onCheckChange(event) 
    const sservicesFormArray: FormArray =
    this.updateSvcForm.get('sservices') as FormArray;


    if (event.target.checked)
    sservicesFormArray.push(new FormControl(event.target.value));

    else
    let i: number = 0;
    sservicesFormArray.controls.forEach((ctrl: FormControl) =>
    if (ctrl.value == event.target.value)
    sservicesFormArray.removeAt(i);
    break;

    i++;
    );

    // set the new value of sservices form array
    this.updateSvcForm.setControl('sservices', sservicesFormArray);






    share|improve this answer























    • I will try but i doubt it work. As this is onCheckChange is triggered only if a checkbox is checked manually.

      – Devora
      Mar 5 at 3:56












    • yup its not working. any other solution?

      – Devora
      Mar 5 at 13:55













    0












    0








    0







    you forget to set the new value of the form Array sservices :



    onCheckChange(event) 
    const sservicesFormArray: FormArray =
    this.updateSvcForm.get('sservices') as FormArray;


    if (event.target.checked)
    sservicesFormArray.push(new FormControl(event.target.value));

    else
    let i: number = 0;
    sservicesFormArray.controls.forEach((ctrl: FormControl) =>
    if (ctrl.value == event.target.value)
    sservicesFormArray.removeAt(i);
    break;

    i++;
    );

    // set the new value of sservices form array
    this.updateSvcForm.setControl('sservices', sservicesFormArray);






    share|improve this answer













    you forget to set the new value of the form Array sservices :



    onCheckChange(event) 
    const sservicesFormArray: FormArray =
    this.updateSvcForm.get('sservices') as FormArray;


    if (event.target.checked)
    sservicesFormArray.push(new FormControl(event.target.value));

    else
    let i: number = 0;
    sservicesFormArray.controls.forEach((ctrl: FormControl) =>
    if (ctrl.value == event.target.value)
    sservicesFormArray.removeAt(i);
    break;

    i++;
    );

    // set the new value of sservices form array
    this.updateSvcForm.setControl('sservices', sservicesFormArray);







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Mar 4 at 15:55









    Mohamed Ali RACHIDMohamed Ali RACHID

    1,878317




    1,878317












    • I will try but i doubt it work. As this is onCheckChange is triggered only if a checkbox is checked manually.

      – Devora
      Mar 5 at 3:56












    • yup its not working. any other solution?

      – Devora
      Mar 5 at 13:55

















    • I will try but i doubt it work. As this is onCheckChange is triggered only if a checkbox is checked manually.

      – Devora
      Mar 5 at 3:56












    • yup its not working. any other solution?

      – Devora
      Mar 5 at 13:55
















    I will try but i doubt it work. As this is onCheckChange is triggered only if a checkbox is checked manually.

    – Devora
    Mar 5 at 3:56






    I will try but i doubt it work. As this is onCheckChange is triggered only if a checkbox is checked manually.

    – Devora
    Mar 5 at 3:56














    yup its not working. any other solution?

    – Devora
    Mar 5 at 13:55





    yup its not working. any other solution?

    – Devora
    Mar 5 at 13:55













    0














    the "easy" way is to create a FormArray with values true/false. see the example in stackblitz



    Update:Correct some errors



    You fill the formArray using the data and the sservicesOptions



    getFormArrayService(data:any[]):FormArray

    //e.g. data=['mopping','washingclothes']
    // return a FormArray and the value will be [false,true,false,true]
    //if data=null, return a FormArray [false,false,false,false]
    return new FormArray(
    this.sservicesOptions.map(x=>new FormControl(data?data.find(dat=>dat==x.value)?true:false:false))
    )



    So, you can, in ngInit make some like



    ngOnInit()

    this.updateSvcForm=new FormGroup(
    sservices:this.getFormArrayService(null)
    )



    And in submitting the form, transform the value



     submit(updateSvcForm)

    if (updateSvcForm.valid)

    let services:string[]=[];
    updateSvcForm.value.sservices.forEach((x,index)=>

    if (x)
    services.push(this.sservicesOptions.value)
    )
    const result=
    ...updateSvcForm.value, //all value of the form but
    sservices:services

    console.log(result)




    The .html becomes like



    <form *ngIf="updateSvcForm" [formGroup]="updateSvcForm" (submit)="submit(updateSvcForm)">
    <div formArrayName="sservices">
    <div *ngFor="let control of updateSvcForm.get('sservices').controls;let i=index">
    <input type="checkbox" [formControlName]="i"/>
    sservicesOptions[i].description

    </div>
    </div>
    <button type="submit">submit</button>
    </form>
    updateSvcForm?.value


    The "not so easy way" a customFormControl, see an example in stackblitz



    Basically, we create a series of the checkbox, each change in checkbox return the "booleansToProp". In the example, I add a property "required", then indicate it is invalid if no check is checked and isString if we can return a string, not an array



    @Component(
    selector: 'check-box-group',
    template: `
    <ng-container *ngFor="let item of source;let i=index;let last=last">

    <div [ngClass]="last?'form-group':''" class="form-check" >
    <input type="checkbox" class="form-check-input" id="_name+''+i"
    [ngModel]="_selectedItems[i]"
    (ngModelChange)="setValue($event,i)" (blur)="onTouched()" >
    <label class="form-check-label" for="_name+''+i">item[_col]</label>
    </div>

    </ng-container>
    `,
    providers: [

    provide: NG_VALUE_ACCESSOR,
    useExisting: forwardRef(() => CheckBoxGroupComponent),
    multi: true
    ,

    provide: NG_VALIDATORS,
    useExisting: forwardRef(() => CheckBoxGroupComponent),
    multi: true,


    ],
    styles:[`
    .focused
    outline: black dotted thin;
    `
    ]
    )
    export class CheckBoxGroupComponent implements ControlValueAccessor null
    if (!this._isRequired)
    return null;
    if (!this._selectedItems.find(x=>x))
    return error:"you must select one option at last"

    return null


    //we received an array (or a string separated by commas) and
    //return an array of true/false
    propsToBoolean(props): any[]
    let propsString=props?props.map(x=>''+x):null;
    return props ? this.source.map((x: any) => propsString.indexOf(''+x[this._key]) >= 0)
    : this.source.map(x => false);



    //we received an array of true/false and return an array with the values
    //or with teh values separated by commas
    booleanToProps(propsBoolean: boolean[])
    let props: any[] = [];
    if (propsBoolean)
    propsBoolean.forEach((item, index) =>
    if (item)
    props.push(this.source[index][this._key])
    )

    return props;









    share|improve this answer

























    • where do i call getFormArrayService?

      – Devora
      Mar 7 at 2:23











    • services.push(this.sservicesOptions.value) and where does these value come from?

      – Devora
      Mar 7 at 2:34











    • @Devora, I update my answer and make a stackbliz. I hope this help you

      – Eliseo
      Mar 7 at 8:07















    0














    the "easy" way is to create a FormArray with values true/false. see the example in stackblitz



    Update:Correct some errors



    You fill the formArray using the data and the sservicesOptions



    getFormArrayService(data:any[]):FormArray

    //e.g. data=['mopping','washingclothes']
    // return a FormArray and the value will be [false,true,false,true]
    //if data=null, return a FormArray [false,false,false,false]
    return new FormArray(
    this.sservicesOptions.map(x=>new FormControl(data?data.find(dat=>dat==x.value)?true:false:false))
    )



    So, you can, in ngInit make some like



    ngOnInit()

    this.updateSvcForm=new FormGroup(
    sservices:this.getFormArrayService(null)
    )



    And in submitting the form, transform the value



     submit(updateSvcForm)

    if (updateSvcForm.valid)

    let services:string[]=[];
    updateSvcForm.value.sservices.forEach((x,index)=>

    if (x)
    services.push(this.sservicesOptions.value)
    )
    const result=
    ...updateSvcForm.value, //all value of the form but
    sservices:services

    console.log(result)




    The .html becomes like



    <form *ngIf="updateSvcForm" [formGroup]="updateSvcForm" (submit)="submit(updateSvcForm)">
    <div formArrayName="sservices">
    <div *ngFor="let control of updateSvcForm.get('sservices').controls;let i=index">
    <input type="checkbox" [formControlName]="i"/>
    sservicesOptions[i].description

    </div>
    </div>
    <button type="submit">submit</button>
    </form>
    updateSvcForm?.value


    The "not so easy way" a customFormControl, see an example in stackblitz



    Basically, we create a series of the checkbox, each change in checkbox return the "booleansToProp". In the example, I add a property "required", then indicate it is invalid if no check is checked and isString if we can return a string, not an array



    @Component(
    selector: 'check-box-group',
    template: `
    <ng-container *ngFor="let item of source;let i=index;let last=last">

    <div [ngClass]="last?'form-group':''" class="form-check" >
    <input type="checkbox" class="form-check-input" id="_name+''+i"
    [ngModel]="_selectedItems[i]"
    (ngModelChange)="setValue($event,i)" (blur)="onTouched()" >
    <label class="form-check-label" for="_name+''+i">item[_col]</label>
    </div>

    </ng-container>
    `,
    providers: [

    provide: NG_VALUE_ACCESSOR,
    useExisting: forwardRef(() => CheckBoxGroupComponent),
    multi: true
    ,

    provide: NG_VALIDATORS,
    useExisting: forwardRef(() => CheckBoxGroupComponent),
    multi: true,


    ],
    styles:[`
    .focused
    outline: black dotted thin;
    `
    ]
    )
    export class CheckBoxGroupComponent implements ControlValueAccessor null
    if (!this._isRequired)
    return null;
    if (!this._selectedItems.find(x=>x))
    return error:"you must select one option at last"

    return null


    //we received an array (or a string separated by commas) and
    //return an array of true/false
    propsToBoolean(props): any[]
    let propsString=props?props.map(x=>''+x):null;
    return props ? this.source.map((x: any) => propsString.indexOf(''+x[this._key]) >= 0)
    : this.source.map(x => false);



    //we received an array of true/false and return an array with the values
    //or with teh values separated by commas
    booleanToProps(propsBoolean: boolean[])
    let props: any[] = [];
    if (propsBoolean)
    propsBoolean.forEach((item, index) =>
    if (item)
    props.push(this.source[index][this._key])
    )

    return props;









    share|improve this answer

























    • where do i call getFormArrayService?

      – Devora
      Mar 7 at 2:23











    • services.push(this.sservicesOptions.value) and where does these value come from?

      – Devora
      Mar 7 at 2:34











    • @Devora, I update my answer and make a stackbliz. I hope this help you

      – Eliseo
      Mar 7 at 8:07













    0












    0








    0







    the "easy" way is to create a FormArray with values true/false. see the example in stackblitz



    Update:Correct some errors



    You fill the formArray using the data and the sservicesOptions



    getFormArrayService(data:any[]):FormArray

    //e.g. data=['mopping','washingclothes']
    // return a FormArray and the value will be [false,true,false,true]
    //if data=null, return a FormArray [false,false,false,false]
    return new FormArray(
    this.sservicesOptions.map(x=>new FormControl(data?data.find(dat=>dat==x.value)?true:false:false))
    )



    So, you can, in ngInit make some like



    ngOnInit()

    this.updateSvcForm=new FormGroup(
    sservices:this.getFormArrayService(null)
    )



    And in submitting the form, transform the value



     submit(updateSvcForm)

    if (updateSvcForm.valid)

    let services:string[]=[];
    updateSvcForm.value.sservices.forEach((x,index)=>

    if (x)
    services.push(this.sservicesOptions.value)
    )
    const result=
    ...updateSvcForm.value, //all value of the form but
    sservices:services

    console.log(result)




    The .html becomes like



    <form *ngIf="updateSvcForm" [formGroup]="updateSvcForm" (submit)="submit(updateSvcForm)">
    <div formArrayName="sservices">
    <div *ngFor="let control of updateSvcForm.get('sservices').controls;let i=index">
    <input type="checkbox" [formControlName]="i"/>
    sservicesOptions[i].description

    </div>
    </div>
    <button type="submit">submit</button>
    </form>
    updateSvcForm?.value


    The "not so easy way" a customFormControl, see an example in stackblitz



    Basically, we create a series of the checkbox, each change in checkbox return the "booleansToProp". In the example, I add a property "required", then indicate it is invalid if no check is checked and isString if we can return a string, not an array



    @Component(
    selector: 'check-box-group',
    template: `
    <ng-container *ngFor="let item of source;let i=index;let last=last">

    <div [ngClass]="last?'form-group':''" class="form-check" >
    <input type="checkbox" class="form-check-input" id="_name+''+i"
    [ngModel]="_selectedItems[i]"
    (ngModelChange)="setValue($event,i)" (blur)="onTouched()" >
    <label class="form-check-label" for="_name+''+i">item[_col]</label>
    </div>

    </ng-container>
    `,
    providers: [

    provide: NG_VALUE_ACCESSOR,
    useExisting: forwardRef(() => CheckBoxGroupComponent),
    multi: true
    ,

    provide: NG_VALIDATORS,
    useExisting: forwardRef(() => CheckBoxGroupComponent),
    multi: true,


    ],
    styles:[`
    .focused
    outline: black dotted thin;
    `
    ]
    )
    export class CheckBoxGroupComponent implements ControlValueAccessor null
    if (!this._isRequired)
    return null;
    if (!this._selectedItems.find(x=>x))
    return error:"you must select one option at last"

    return null


    //we received an array (or a string separated by commas) and
    //return an array of true/false
    propsToBoolean(props): any[]
    let propsString=props?props.map(x=>''+x):null;
    return props ? this.source.map((x: any) => propsString.indexOf(''+x[this._key]) >= 0)
    : this.source.map(x => false);



    //we received an array of true/false and return an array with the values
    //or with teh values separated by commas
    booleanToProps(propsBoolean: boolean[])
    let props: any[] = [];
    if (propsBoolean)
    propsBoolean.forEach((item, index) =>
    if (item)
    props.push(this.source[index][this._key])
    )

    return props;









    share|improve this answer















    the "easy" way is to create a FormArray with values true/false. see the example in stackblitz



    Update:Correct some errors



    You fill the formArray using the data and the sservicesOptions



    getFormArrayService(data:any[]):FormArray

    //e.g. data=['mopping','washingclothes']
    // return a FormArray and the value will be [false,true,false,true]
    //if data=null, return a FormArray [false,false,false,false]
    return new FormArray(
    this.sservicesOptions.map(x=>new FormControl(data?data.find(dat=>dat==x.value)?true:false:false))
    )



    So, you can, in ngInit make some like



    ngOnInit()

    this.updateSvcForm=new FormGroup(
    sservices:this.getFormArrayService(null)
    )



    And in submitting the form, transform the value



     submit(updateSvcForm)

    if (updateSvcForm.valid)

    let services:string[]=[];
    updateSvcForm.value.sservices.forEach((x,index)=>

    if (x)
    services.push(this.sservicesOptions.value)
    )
    const result=
    ...updateSvcForm.value, //all value of the form but
    sservices:services

    console.log(result)




    The .html becomes like



    <form *ngIf="updateSvcForm" [formGroup]="updateSvcForm" (submit)="submit(updateSvcForm)">
    <div formArrayName="sservices">
    <div *ngFor="let control of updateSvcForm.get('sservices').controls;let i=index">
    <input type="checkbox" [formControlName]="i"/>
    sservicesOptions[i].description

    </div>
    </div>
    <button type="submit">submit</button>
    </form>
    updateSvcForm?.value


    The "not so easy way" a customFormControl, see an example in stackblitz



    Basically, we create a series of the checkbox, each change in checkbox return the "booleansToProp". In the example, I add a property "required", then indicate it is invalid if no check is checked and isString if we can return a string, not an array



    @Component(
    selector: 'check-box-group',
    template: `
    <ng-container *ngFor="let item of source;let i=index;let last=last">

    <div [ngClass]="last?'form-group':''" class="form-check" >
    <input type="checkbox" class="form-check-input" id="_name+''+i"
    [ngModel]="_selectedItems[i]"
    (ngModelChange)="setValue($event,i)" (blur)="onTouched()" >
    <label class="form-check-label" for="_name+''+i">item[_col]</label>
    </div>

    </ng-container>
    `,
    providers: [

    provide: NG_VALUE_ACCESSOR,
    useExisting: forwardRef(() => CheckBoxGroupComponent),
    multi: true
    ,

    provide: NG_VALIDATORS,
    useExisting: forwardRef(() => CheckBoxGroupComponent),
    multi: true,


    ],
    styles:[`
    .focused
    outline: black dotted thin;
    `
    ]
    )
    export class CheckBoxGroupComponent implements ControlValueAccessor null
    if (!this._isRequired)
    return null;
    if (!this._selectedItems.find(x=>x))
    return error:"you must select one option at last"

    return null


    //we received an array (or a string separated by commas) and
    //return an array of true/false
    propsToBoolean(props): any[]
    let propsString=props?props.map(x=>''+x):null;
    return props ? this.source.map((x: any) => propsString.indexOf(''+x[this._key]) >= 0)
    : this.source.map(x => false);



    //we received an array of true/false and return an array with the values
    //or with teh values separated by commas
    booleanToProps(propsBoolean: boolean[])
    let props: any[] = [];
    if (propsBoolean)
    propsBoolean.forEach((item, index) =>
    if (item)
    props.push(this.source[index][this._key])
    )

    return props;










    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Mar 7 at 8:06

























    answered Mar 6 at 14:54









    EliseoEliseo

    6,6531314




    6,6531314












    • where do i call getFormArrayService?

      – Devora
      Mar 7 at 2:23











    • services.push(this.sservicesOptions.value) and where does these value come from?

      – Devora
      Mar 7 at 2:34











    • @Devora, I update my answer and make a stackbliz. I hope this help you

      – Eliseo
      Mar 7 at 8:07

















    • where do i call getFormArrayService?

      – Devora
      Mar 7 at 2:23











    • services.push(this.sservicesOptions.value) and where does these value come from?

      – Devora
      Mar 7 at 2:34











    • @Devora, I update my answer and make a stackbliz. I hope this help you

      – Eliseo
      Mar 7 at 8:07
















    where do i call getFormArrayService?

    – Devora
    Mar 7 at 2:23





    where do i call getFormArrayService?

    – Devora
    Mar 7 at 2:23













    services.push(this.sservicesOptions.value) and where does these value come from?

    – Devora
    Mar 7 at 2:34





    services.push(this.sservicesOptions.value) and where does these value come from?

    – Devora
    Mar 7 at 2:34













    @Devora, I update my answer and make a stackbliz. I hope this help you

    – Eliseo
    Mar 7 at 8:07





    @Devora, I update my answer and make a stackbliz. I hope this help you

    – Eliseo
    Mar 7 at 8:07











    0














    The reason for this, is that you are using checked to mark which checkboxes should be checked, they have no correlation to your form array, so if you do not touch the checkboxes, the formarray will correctly be empty.



    I can come up with a couple options to solve this... also the following changes:



    change function could be changed to this:



    onCheckChange(event) 
    if (event.target.checked)
    this.ssArray.push(this.fb.control(event.target.value));

    else
    this.ssArray.removeAt(this.ssArray.value.findIndex(x => x === event.target.value))




    Doesn't matter how you do it, your way works as well :) I also like using FormBuilder (here injected as fb).



    I like to use a getter in this case:



    get ssArray() 
    return this.updateSvcForm.get('sservices') as FormArray;



    The options I can think of:



    1. add a checked property to the objects in your array sservicesOptions

    2. Keep your isSelected function, but add the chosen options to your formarray initially


    I like option 1 best, so add a checked property to the objects:



    servicesOptions = [
    description: '1. Sweeping', value: 'sweeping', checked: false ,
    description: '2. Mopping', value: 'mopping', checked: false ,
    description: '3. Windows', value: 'windows', checked: false ,
    description: '4. Washing Clothes', value: 'washingclothes', checked: false ,
    ];


    Then when you build the form, change the checked status for those that should be preselected, and also add the values that should be checked to your form array:



    constructor(private fb: FormBuilder) 
    this.updateSvcForm = this.fb.group(
    sservices: this.fb.array([]),
    );
    // change the checked status for the checkboxes that should be checked
    this.servicesOptions.map(x =>
    this.empDetails.services.indexOf(x) >= 0 ? x.checked = true : x.checked = false)
    // initially set the selected form controls to the formarray
    this.empDetails.services.map((x) => this.ssArray.push(this.fb.control(x)))



    Then you can add [checked]="service.checked" in template.



    DEMO




    Option 2:



    Keep your checked function like you have, just remember to add the prechosen values to your formarray. I don't really like this option, since for example, we end up calling a function in template, which is really not recommended. But anyway, keep the code as the same as you have now, just add the intial values to the formarray:



    this.updateSvcForm = this.fb.group(
    sservices: this.fb.array([]),
    );
    // add the intial values to the formarray:
    this.empDetails.services.map((x) => this.ssArray.push(this.fb.control(x)))


    DEMO



    I added a console.log inside the function, to show how it is called. It's okay for a demo like this, but if you have a big form, I would really caution for you to use this solution.




    There would be a third option, to actually set all values to your form array, and then just toggle the boolean value of the checkbox, but that would require some refactoring of code, which I don't know if you want. But there is that option too.






    share|improve this answer



























      0














      The reason for this, is that you are using checked to mark which checkboxes should be checked, they have no correlation to your form array, so if you do not touch the checkboxes, the formarray will correctly be empty.



      I can come up with a couple options to solve this... also the following changes:



      change function could be changed to this:



      onCheckChange(event) 
      if (event.target.checked)
      this.ssArray.push(this.fb.control(event.target.value));

      else
      this.ssArray.removeAt(this.ssArray.value.findIndex(x => x === event.target.value))




      Doesn't matter how you do it, your way works as well :) I also like using FormBuilder (here injected as fb).



      I like to use a getter in this case:



      get ssArray() 
      return this.updateSvcForm.get('sservices') as FormArray;



      The options I can think of:



      1. add a checked property to the objects in your array sservicesOptions

      2. Keep your isSelected function, but add the chosen options to your formarray initially


      I like option 1 best, so add a checked property to the objects:



      servicesOptions = [
      description: '1. Sweeping', value: 'sweeping', checked: false ,
      description: '2. Mopping', value: 'mopping', checked: false ,
      description: '3. Windows', value: 'windows', checked: false ,
      description: '4. Washing Clothes', value: 'washingclothes', checked: false ,
      ];


      Then when you build the form, change the checked status for those that should be preselected, and also add the values that should be checked to your form array:



      constructor(private fb: FormBuilder) 
      this.updateSvcForm = this.fb.group(
      sservices: this.fb.array([]),
      );
      // change the checked status for the checkboxes that should be checked
      this.servicesOptions.map(x =>
      this.empDetails.services.indexOf(x) >= 0 ? x.checked = true : x.checked = false)
      // initially set the selected form controls to the formarray
      this.empDetails.services.map((x) => this.ssArray.push(this.fb.control(x)))



      Then you can add [checked]="service.checked" in template.



      DEMO




      Option 2:



      Keep your checked function like you have, just remember to add the prechosen values to your formarray. I don't really like this option, since for example, we end up calling a function in template, which is really not recommended. But anyway, keep the code as the same as you have now, just add the intial values to the formarray:



      this.updateSvcForm = this.fb.group(
      sservices: this.fb.array([]),
      );
      // add the intial values to the formarray:
      this.empDetails.services.map((x) => this.ssArray.push(this.fb.control(x)))


      DEMO



      I added a console.log inside the function, to show how it is called. It's okay for a demo like this, but if you have a big form, I would really caution for you to use this solution.




      There would be a third option, to actually set all values to your form array, and then just toggle the boolean value of the checkbox, but that would require some refactoring of code, which I don't know if you want. But there is that option too.






      share|improve this answer

























        0












        0








        0







        The reason for this, is that you are using checked to mark which checkboxes should be checked, they have no correlation to your form array, so if you do not touch the checkboxes, the formarray will correctly be empty.



        I can come up with a couple options to solve this... also the following changes:



        change function could be changed to this:



        onCheckChange(event) 
        if (event.target.checked)
        this.ssArray.push(this.fb.control(event.target.value));

        else
        this.ssArray.removeAt(this.ssArray.value.findIndex(x => x === event.target.value))




        Doesn't matter how you do it, your way works as well :) I also like using FormBuilder (here injected as fb).



        I like to use a getter in this case:



        get ssArray() 
        return this.updateSvcForm.get('sservices') as FormArray;



        The options I can think of:



        1. add a checked property to the objects in your array sservicesOptions

        2. Keep your isSelected function, but add the chosen options to your formarray initially


        I like option 1 best, so add a checked property to the objects:



        servicesOptions = [
        description: '1. Sweeping', value: 'sweeping', checked: false ,
        description: '2. Mopping', value: 'mopping', checked: false ,
        description: '3. Windows', value: 'windows', checked: false ,
        description: '4. Washing Clothes', value: 'washingclothes', checked: false ,
        ];


        Then when you build the form, change the checked status for those that should be preselected, and also add the values that should be checked to your form array:



        constructor(private fb: FormBuilder) 
        this.updateSvcForm = this.fb.group(
        sservices: this.fb.array([]),
        );
        // change the checked status for the checkboxes that should be checked
        this.servicesOptions.map(x =>
        this.empDetails.services.indexOf(x) >= 0 ? x.checked = true : x.checked = false)
        // initially set the selected form controls to the formarray
        this.empDetails.services.map((x) => this.ssArray.push(this.fb.control(x)))



        Then you can add [checked]="service.checked" in template.



        DEMO




        Option 2:



        Keep your checked function like you have, just remember to add the prechosen values to your formarray. I don't really like this option, since for example, we end up calling a function in template, which is really not recommended. But anyway, keep the code as the same as you have now, just add the intial values to the formarray:



        this.updateSvcForm = this.fb.group(
        sservices: this.fb.array([]),
        );
        // add the intial values to the formarray:
        this.empDetails.services.map((x) => this.ssArray.push(this.fb.control(x)))


        DEMO



        I added a console.log inside the function, to show how it is called. It's okay for a demo like this, but if you have a big form, I would really caution for you to use this solution.




        There would be a third option, to actually set all values to your form array, and then just toggle the boolean value of the checkbox, but that would require some refactoring of code, which I don't know if you want. But there is that option too.






        share|improve this answer













        The reason for this, is that you are using checked to mark which checkboxes should be checked, they have no correlation to your form array, so if you do not touch the checkboxes, the formarray will correctly be empty.



        I can come up with a couple options to solve this... also the following changes:



        change function could be changed to this:



        onCheckChange(event) 
        if (event.target.checked)
        this.ssArray.push(this.fb.control(event.target.value));

        else
        this.ssArray.removeAt(this.ssArray.value.findIndex(x => x === event.target.value))




        Doesn't matter how you do it, your way works as well :) I also like using FormBuilder (here injected as fb).



        I like to use a getter in this case:



        get ssArray() 
        return this.updateSvcForm.get('sservices') as FormArray;



        The options I can think of:



        1. add a checked property to the objects in your array sservicesOptions

        2. Keep your isSelected function, but add the chosen options to your formarray initially


        I like option 1 best, so add a checked property to the objects:



        servicesOptions = [
        description: '1. Sweeping', value: 'sweeping', checked: false ,
        description: '2. Mopping', value: 'mopping', checked: false ,
        description: '3. Windows', value: 'windows', checked: false ,
        description: '4. Washing Clothes', value: 'washingclothes', checked: false ,
        ];


        Then when you build the form, change the checked status for those that should be preselected, and also add the values that should be checked to your form array:



        constructor(private fb: FormBuilder) 
        this.updateSvcForm = this.fb.group(
        sservices: this.fb.array([]),
        );
        // change the checked status for the checkboxes that should be checked
        this.servicesOptions.map(x =>
        this.empDetails.services.indexOf(x) >= 0 ? x.checked = true : x.checked = false)
        // initially set the selected form controls to the formarray
        this.empDetails.services.map((x) => this.ssArray.push(this.fb.control(x)))



        Then you can add [checked]="service.checked" in template.



        DEMO




        Option 2:



        Keep your checked function like you have, just remember to add the prechosen values to your formarray. I don't really like this option, since for example, we end up calling a function in template, which is really not recommended. But anyway, keep the code as the same as you have now, just add the intial values to the formarray:



        this.updateSvcForm = this.fb.group(
        sservices: this.fb.array([]),
        );
        // add the intial values to the formarray:
        this.empDetails.services.map((x) => this.ssArray.push(this.fb.control(x)))


        DEMO



        I added a console.log inside the function, to show how it is called. It's okay for a demo like this, but if you have a big form, I would really caution for you to use this solution.




        There would be a third option, to actually set all values to your form array, and then just toggle the boolean value of the checkbox, but that would require some refactoring of code, which I don't know if you want. But there is that option too.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered yesterday









        AJT_82AJT_82

        36.6k136999




        36.6k136999



























            draft saved

            draft discarded
















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54984196%2fbinding-data-to-angular-checkbox%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            1928 у кіно

            Захаров Федір Захарович

            Ель Греко