2
votes

I am recently stuck creating a really big form. It has mostly simple textfields, but a lot of them and additionally an array of child-objects. From the backend (Django Rest Framework) I receive this as an object with nested positions. These Child-Objects should be displayed in an editable and validatable mat-table with mat-form-fields.

This is a part of the model:

export class Auftrag{ // <-- parent
  auftrag: number = null;
  bezeichnung: string = '';
  datum: Date = null;
  ueberwachen: boolean = null;
  erl: boolean = null;
  [...]
  auftragposition:Array<AuftragPosition> = null;  //<-- children
}

export class AuftragPosition {
  id: number = null;
  auftrag: number = null;
  position: number = null;
  menge: number = null;
  einheit: string = "";
  beschreibung: string = "";
  teil_nr: string = "";
  artikel: string = ""
  ep: number = null;
  rabatt: number = null;
 }

The single textfields work as reactive form fields, I create is as following (because there are really many fields), and it works:

this.auftragForm = this.fb.group(new Auftrag()); //fb is a formbuilder

The reason I do this is because I have to write the big model in django, then in anguilar and I don't want to write all of that again when I create a form.. It also created the field "auftragposition", which (checked in the log) is an array with multiple objects (auftragposition). These should be displayed in the mat-table. The mat-table is a different sub-component, so I pass the form like following:

in parent component (auftragdetail.component.html):

<app-auftragposition [parentFormGroup]="auftragForm"></app-auftragposition>

in mat-table component (auftragposition.component.ts):

@Input() parentFormGroup: FormGroup;

in auftragposition.comopnent.html:

<div class="auftragposition" [formGroup]="parentFormGroup">
    <mat-table class="auftragposition-table mat-elevation-z8" formArrayName="auftragposition" [dataSource]="dataSource"
            matSort matSortActive="position" matSortDirection="desc" matSortDisableClear> [...]

Problem here is the datasource. It's kind of confusing, because mat-fields don't need datasources - they get filled through the form. I know I can input an simple array as datasource. I made a mock array and it showed the data. But 1) I can't get an array out of the reactive form (tried many things with .get('') and .value) and 2) I don't think it will be wired to the reactive forms and pass the data back when I submit...

Maybe the problem is how I create my reactive form. As far as I could do research, the mat-table needs an formarray filled with one formgroup as row. Maybe the way I simply pass in the object does not create a real formarray.

I could also find this stackblitz, where someone wrote a special datasource (which I moght have to do here), but it doesn't really helmp me, since it does not get populated with existing data in the example: some Stackblitz example

I would be thankful for any kind of hints.

1
Perhaps this helps: medium.com/@nsrathore/… - mohsenmadi

1 Answers

1
votes

Just came back to this - it's really simple. You can just use the formArray as DataSource. Make sure to cast it to FormArray first, otherwise it stays an AbstractControl.

dataSource = (this.yourForm.controls.yourFormArray as FormArray).value)