The current configuration functions properly when I toggle checkboxes and submit to the server.
However, upon reloading the page or entering edit mode, everything loads correctly and the checkboxes are checked with the corresponding entries displayed like this...
https://i.sstatic.net/9z7PB.png
The issue arises when I attempt to submit without making any changes, resulting in an empty array being submitted permission_ids: []
. To trigger the OnChange()
event, each checkbox needs to be clicked again; however, as a newcomer to Angular, I'm unsure how to automate this process upon page load.
My understanding of the problem is that while the checkboxes appear checked, the form values are not being updated accordingly.
Below is the code:
Template
<h4>Permissions</h4>
<div class="form-group row p-t-20">
<div class="col-sm-4">
<div class="custom-control custom-checkbox" *ngFor="let perm of permissions; let i=index">
<input
type="checkbox"
class="custom-control-input"
id="permission_{{perm.id}}"
[value]="perm.id"
(change)="onPermissionCheckboxChange($event)"
[checked]="permissionExists(perm.id)">
<label
class="custom-control-label"
for="permission_{{perm.id}}">
{{ perm.name }}
</label>
</div>
</div>
</div>
Typescript
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, FormArray, FormControl, Validators } from "@angular/forms";
import { NotificationService } from "../../notification/notification.service";
import { PermissionsService } from "../../permissions/permissions.service";
import { HttpClient } from "@angular/common/http";
import { environment } from "../../../../environments/environment";
import { Router, ActivatedRoute } from "@angular/router";
import { RolesService } from "../roles.service";
@Component({
selector: 'app-edit-role',
templateUrl: './edit-role.component.html',
styleUrls: ['./edit-role.component.css']
})
export class EditRoleComponent implements OnInit {
isLoading: boolean = false;
roleId: number = +this.route.snapshot.params['id']
roleObj: any = {};
haveRole: any = true;
roles: any;
role: any;
permissions: any;
form: FormGroup;
constructor(
private http: HttpClient,
private router: Router,
private route: ActivatedRoute,
private fb: FormBuilder,
private notificationService: NotificationService,
private rolesService: RolesService,
private permissionsService: PermissionsService
) {
this.form = this.fb.group({
role: new FormGroup({
name: new FormControl('', [Validators.required]),
permission_ids: this.fb.array([])
})
})
}
permissionExists(id: number) {
return this.role.permissions.find(function(el: any){ return el.id === id }) !== undefined;
}
ngOnInit(): void {
this.rolesService.getRoles().subscribe(response => {
this.roles = response.body;
this.role = this.roles.find((el: any) => el.id === this.roleId)
//console.log(this.role);
this.isLoading = false;
this.form.patchValue({
'role': {
'name': this.role.name
}
});
},
error => {
this.isLoading = false;
this.notificationService.showNotification(
error.error.title,
error.error.details,
'error'
);
})
this.permissionsService.getPermissions().subscribe(response => {
this.permissions = response.body;
this.isLoading = false;
},
error => {
this.isLoading = false;
// console.log(error.error);
this.notificationService.showNotification(
error.error.title,
error.error.details,
'error'
);
})
}
onPermissionCheckboxChange(e: any) {
const checkArray: FormArray = this.form.get('role.permission_ids') as FormArray;
if (e.target.checked) {
checkArray.push(new FormControl(e.target.value));
} else {
let i: number = 0;
checkArray.controls.forEach((item: any) => {
if (item.value == e.target.value) {
checkArray.removeAt(i);
return;
}
i++;
});
}
}
onSubmit() {
this.roleObj.role = this.form.value.role
console.log(this.roleObj)
}
}
Apologies for the less than stellar code quality, still adapting to Angular coming from a primarily Ruby on Rails background.