3

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.

2 Answers 2

3

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, bracket removed. Still my main doubt here was about the values that stored both in the array value and in the controls value. I'm afraid that ignoring it might cause bugs in the future
1

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

1 Comment

Thanks for saying 'regular JS object'. I had to here it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.