Home

Published

- 2 min read

Angular Typed Forms from generated dtos

img of Angular Typed Forms from generated dtos

If you need to create a form in Angular, you can use the FormGroup and FormControl classes from @angular/forms. Meanwhile Angular supports typed forms. If you just want to create a form which holds all values from the DTO you can use the following approach.

   // migration-expert-or-ic-dto.ts
export interface MigrationExpertOrIcDto { 
    id?: string | null;
    user: UserDto;
    personalNumberFromAnalytics: number;
    hasConflict: boolean;
    isPrimary: boolean;
    roleId: number;
    version?: number | null;
}

In your Angular component you can define a new type like this: (You can find some documentation for this here: https://www.typescriptlang.org/docs/handbook/2/mapped-types.html)

   // migration-expert-or-ic.component.ts
type MigrationExpertOrIc = {
  [Property in keyof MigrationExpertOrIcDto]: FormControl<MigrationExpertOrIcDto[Property]>;
}

And then you can use the type to create a form like this. Note that We are not using the formBuilder completeley because we might have nullable and nonnullable fields mixed.

   // migration-expert-or-ic.component.ts
public form: FormGroup<MigrationExpertOrIc>;

//...

public ngOnInit(): void {
  this.form = this.formBuilder.group<MigrationExpertOrIc>({
  id: new FormControl(null),
  user: new FormControl(null),
  personalNumberFromAnalytics: new FormControl(null),
  hasConflict: new FormControl(null),
  isPrimary: new FormControl(null),
  roleId: new FormControl(null),
  version: new FormControl(null)
});

If we have an explicit form and all properties are non nullable it can look like this:

   // audio-buttons.component.ts
import { Component } from '@angular/core';
import { AudioService } from '../services/audio.service';
import { FormBuilder, FormControl, FormGroup } from '@angular/forms';

interface VolumeForm { 
  volume: FormControl<number>; 
} 

@Component({
  selector: 'app-audio-buttons',
  templateUrl: './audio-buttons.component.html',
  styleUrls: ['./audio-buttons.component.scss']
})
export class AudioButtonsComponent {
  public volumeForm: FormGroup<VolumeForm>; 

  public constructor(
    private audioService: AudioService,
    private formbuilder: FormBuilder) { 
      this.volumeForm = this.formbuilder.nonNullable.group({ 
        volume: [1] 
      }); 
  }
}