1
votes

I have a form dynamically generated of checkboxes, and an initial get request that grabs the form data from the server (which checkboxes are checked and unchecked, which is defined by the value being either 0 or 1 for true or false) When i click a checkbox, it is supposed to switch (checked/unchecked) as well as send the correct put request (opposite of the current value (0 to 1, 1 to 0). right now, all checkboxes that are unchecked function as expected. but boxes that are checked from the initial get, click once, and go unchecked and send a 1 when it should send a 0, and if clicked again, remain unchecked but send the correct output of 0, then that checkbox functions correctly from then on. what is happening that is screwing up the first click of only checked boxes?

comp

places;
    ready = false;
    countriesForm: FormGroup;

constructor(private whiteListService: WhiteListService) {}

ngOnInit() {
    // get places list with status'
    this.whiteListService.getList()
        .subscribe(
            (response: Response) => {
                console.log(response.statusText);
                this.places = response.json();
                this.createList(this.places.countries);
            },
            (error) => console.log(error)
        );
}

createList(places) {
    // assign this.places for dom binding access
    this.places = places;
    console.log(places)
    this.countriesForm = new FormGroup({});
    for (let i = 0; i < this.places.length; i++) {
        this.countriesForm.addControl(
            this.places[i].name, new FormControl()
        );
    }
    this.ready = true;
}

toggleAllowed(place, event) {
    // send authorization of country to server
    console.log('allow before switch', place.allow);
    place.allow === 1 ? place.allow = 0 : place.allow = 1;
    console.log('allow after switch', place.allow);
    console.log(this.places);
    this.whiteListService.sendAllow(place.code, place.allow)
        .subscribe(
            (response) => console.log(response),
            (error) => {
                console.log(error);
                place.allow = !place.allow;
            }
        );
}

}

html

<div class="geo-list">
    <div class="content-box container">
         <form *ngIf="ready" [formGroup]="countriesForm">
            <div class="place" *ngFor="let place of places">
                <input
                    type="checkbox"
                    formControlName="{{place.name}}"
                    value="{{place.allow}}"
                    (change)="toggleAllowed(place, $event)"
                    [checked]="place.allow == 1"
                >
                {{ place.name }} | {{ place.code }} | {{ place.continent }} | {{ place.allow }}
            </div>
        </form>
    </div>
</div>
2

2 Answers

1
votes

You need to set the value to the form control, because as it is now, no matter if the box is checked or not, the value will initially be null for your form controls.

We can solve this by in your iteration you can set the value as true or false depending on the numeric value.

for (let i = 0; i < this.places.length; i++) {
  this.countriesForm.addControl(
     this.places[i].name, new FormControl(this.places[i].allow == 1 ? true : false)
  );
}

and then you can get rid of the checked in your template:

<input
   type="checkbox"
   formControlName="{{place.name}}"
   (change)="toggleAllowed(place, $event)"
>

As a sidenote, in theory you'd not need to toggle between 0 and 1 with true and false, as per said here: Is true == 1 and false == 0 in JavaScript? But I'd stick with using true and false :)

0
votes

Alright, so i fixed this, by changing the switch function in the toggleAllowed function use a '==' instead of '==='. while ts lint flags this and suggests '===' it just wont work with '==='. not sure why.

this method works with predefining the control values, or defining them with a [check]="place.allow".