Constructing a signal-first type in Angular


// registration.mannequin.ts
export interface RegistrationData {
  e-mail: string;
  password: string;
  confirmPassword: string;
  acceptedTerms: boolean;
}

This interface mirrors what would usually be despatched to a back-end API. There isn’t a duplication of state, no separate “type worth” object, and no mapping required at submission time.

Creating the signal-backed type

The shape itself is created within the part utilizing a writable sign because the supply of reality. The type() operate attaches type semantics validation, discipline state, and submission to that sign.

// registration.part.ts
import { CommonModule } from "@angular/widespread";
import { Part, sign } from "@angular/core";
import {
  e-mail,
  type,
  FormField,
  required,
  submit,
} from "@angular/kinds/indicators";
import { RegistrationData } from "./registration.mannequin";

@Part({
  selector: "app-registration",
  imports: [FormField, CommonModule],
  templateUrl: "./registration.html",
  styleUrl: "./registration.css",
})
export class Registration {
  readonly mannequin = sign({
    e-mail: "",
    password: "",
    confirmPassword: "",
    acceptedTerms: false,
  });

  readonly registrationForm = type(this.mannequin, (schema) => {
    required(schema.e-mail, { message: "Electronic mail is required" });
    e-mail(schema.e-mail, { message: "Enter a sound e-mail handle" });

    required(schema.password, { message: "Password is required" });
    required(schema.confirmPassword, {
      message: "Please affirm your password",
    });

    required(schema.acceptedTerms, {
      message: "You should settle for the phrases to proceed",
    });
  });

  async onSubmit(occasion?: Occasion) {
    occasion?.preventDefault();

    await submit(this.registrationForm, (worth) => {
      console.log(worth());
      // Mock Server Name
      return Promise.resolve([
        {
          kind: "EmailAlreadyExists",
          field: this.registrationForm.email,
          error: { kind: "server", message: "Email already taken" },
        },
      ]);
    });
  }
}

A number of design choices are price noting.