I've implemented formArray sortBy function in my angular app by sorting the formArray value and patch it after the sorting.
sortBy(FieldName: string) {
let array = this.myItems.value;
array.value.sort((a, b) => a[FieldName] - b[FieldName]);
array.controls.sort((a, b) => a.value[FieldName] - b.value[FieldName]);
this.myForm.controls.myItems.patchValue(array);
}
As you can see I had to sort both the formArray controls and its value.
My question is, Should I really sort it both or there is a better practice or a build in way of doing it. It looks like the controls and the value should be binded somehow.
CodePudding user response:
Yes, you need to "kinda" sort by both, though you can make a one-liner of it. We need to remember, when you call myItems.value
, this is just a regular JS object, and the formarray is no longer tied to this, in the sense that if you modify myItems.value
afterwards, it will not reflect in the formarray, as the formarray is an array of formcontrols/formgroups, not a regular JS array. The myItems.value
will also just reflect the current state of the formarray value, so if you assign it to a variable and then change the value of the formarray, the assigned variable will have the original value.
So as for the oneliner... You can do
this.myItems.setValue(this.myItems.value.sort((a, b) => a[FieldName] - b[FieldName]));
And as mentioned in other answer, remove the bracket when building the form:
myItems: myFormArray
YOUR MODIFIED STACKBLITZ
CodePudding user response:
Just sorting by control
is enough.
First, set myItem
to this.form
without bracket.
this.myForm = this.formBuilder.group({
header: ['hello form'],
myItems: myFormArray,
});
Then sort your FormArray
by controls
.
sortBy(FieldName: string) {
this.myItems.controls.sort((a, b) => a.value[FieldName] - b.value[FieldName]);
}
If you need sorted myArray
, you can get it by this.myForm.getRawValue().myItems
.