Home

Published

- 2 min read

Angular Typed Forms from generated dtos

img of Angular Typed Forms from generated dtos
img of 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] 
      }); 
  }
}