Home > front end >  Does sorting Angular reactive form array really requires sorting both controls and value?
Does sorting Angular reactive form array really requires sorting both controls and value?

Time:11-30

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);
}

Working Stackblitz example

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.

  • Related