Use Cases (Aktualisiert: 2.6.2026)

Claude Code für Angular: CLI, Standalone Components, Forms, HTTP und Tests

Praxisworkflow mit Claude Code für Angular CLI, Standalone Components, Reactive Forms, HttpClient, Tests und Review.

Claude Code für Angular: CLI, Standalone Components, Forms, HTTP und Tests

Claude Code ist in Angular-Projekten am stärksten, wenn es nicht nur einzelne Komponenten erzeugt, sondern den vorhandenen Code liest und innerhalb klarer Grenzen arbeitet. Eine reale Änderung betrifft oft Angular CLI, Standalone Components, Reactive Forms, einen typisierten Service mit HttpClient, Unit Tests, E2E-Tests und eine kritische Review.

Ein Standalone Component ist ein Angular-Component, der seine Abhängigkeiten direkt in imports deklariert und nicht über ein NgModule registriert werden muss. Reactive Forms bedeutet, dass Formularwerte und Validierungsregeln explizit in TypeScript modelliert werden. HttpClient ist die offizielle Angular-API für Backend-Kommunikation. Wenn diese Begriffe im Prompt fehlen, erzeugt Claude Code schnell Code, der zwar funktioniert, aber nicht zum Projektstil passt.

Als technische Referenz verwende ich die offiziellen Seiten: Angular CLI, Reactive forms, HttpClient, Angular testing und Claude Code workflows. Ergänzend passen TypeScript-Tipps, Testing-Strategien und CLAUDE.md Best Practices.

Arbeitsrahmen festlegen

Beginnen Sie nicht mit “baue ein Formular”. Bitten Sie Claude Code zuerst um Analyse. Ein Harness ist der sichere Arbeitsrahmen für den Agenten: erlaubte Dateien, Konventionen, Testbefehle und Review-Kriterien.

Lies dieses Angular-Projekt, bevor du Dateien änderst. Prüfe package.json, angular.json und src/app.
Fasse zusammen, ob Standalone Components verwendet werden, welcher Test Runner aktiv ist,
wo HttpClient bereitgestellt wird und welche Namenskonventionen erkennbar sind.
Noch keine Dateien bearbeiten.
BereichAufgabe für Claude CodeEntscheidung des Teams
Angular CLIGeneratorbefehle, Dateipfade, AbhängigkeitenRouting-Grenzen, Namensregeln
Componentimports, Template, Signals, EventsUI-Text, Accessibility, Release-Risiko
Reactive FormsFormGroup, Validatoren, Submit-Statusfachliche Regeln
Service / HTTPTypen, API-Methoden, Test-BackendAPI-Vertrag, Auth, Fehlerpolitik
TestsUnit, E2E, RegressionenCoverage-Ziel, Merge-Freigabe
flowchart LR
  P[Prompt] --> C[Angular CLI]
  C --> A[Standalone component]
  A --> F[Reactive Forms]
  A --> S[Ticket service]
  S --> H[HttpClient]
  F --> U[Unit tests]
  A --> E[E2E tests]
  U --> R[Review]
  E --> R

Mit Angular CLI eine prüfbare Basis schaffen

Für ein neues Experiment ist Angular CLI der einfachste Startpunkt. In einem bestehenden Repository sollte Claude Code zuerst die aktuelle Konfiguration lesen.

npm install -g @angular/cli
ng new support-desk-angular --standalone --routing --style css
cd support-desk-angular
ng generate component features/tickets/ticket-intake --standalone
ng generate service data/ticket
ng test

Der Testlauf vor der Änderung ist wichtig. Wenn ng test bereits vorher fehlschlägt, vermischen sich alte Probleme mit neuen Regressionen. Bei paralleler Arbeit im Team gehört außerdem in den Prompt, dass nur der vereinbarte Feature-Bereich verändert und keine uncommitted Changes anderer Personen zurückgesetzt werden.

Zuerst den typisierten Service bauen

Ich starte bei Angular-Formularen gern mit dem Service. Der API-Vertrag ist dann sichtbar, und der Component bleibt für UI-Zustand zuständig.

import { HttpClient } from '@angular/common/http';
import { inject, Injectable } from '@angular/core';
import { Observable } from 'rxjs';

export type TicketPriority = 'low' | 'medium' | 'high';

export interface TicketDraft {
  title: string;
  email: string;
  priority: TicketPriority;
  message: string;
}

export interface Ticket extends TicketDraft {
  id: string;
  createdAt: string;
}

@Injectable({ providedIn: 'root' })
export class TicketService {
  private readonly http = inject(HttpClient);
  private readonly baseUrl = '/api/tickets';

  listTickets(): Observable<Ticket[]> {
    return this.http.get<Ticket[]>(this.baseUrl);
  }

  createTicket(draft: TicketDraft): Observable<Ticket> {
    return this.http.post<Ticket>(this.baseUrl, draft);
  }
}

In einer Standalone-App wird HttpClient in app.config.ts bereitgestellt.

import { ApplicationConfig } from '@angular/core';
import { provideRouter } from '@angular/router';
import { provideHttpClient } from '@angular/common/http';
import { routes } from './app.routes';

export const appConfig: ApplicationConfig = {
  providers: [provideRouter(routes), provideHttpClient()],
};

Ein konkreter Fehler ist ein Service, der zusätzlich UI-Texte, Retry-Entscheidungen und lokalen Screen-State enthält. Der Service sollte langweilig bleiben: Endpoint, Typen, Kommunikation. Die Oberfläche entscheidet, wie ein Fehler formuliert wird.

Standalone Reactive Form implementieren

Der Component nutzt Reactive Forms und ein Signal für den Speichervorgang. Im Prompt sollte stehen, dass ngModel nicht verwendet werden darf.

import { Component, computed, inject, signal } from '@angular/core';
import { ReactiveFormsModule, FormControl, FormGroup, Validators } from '@angular/forms';
import { finalize } from 'rxjs';
import { Ticket, TicketService, TicketPriority } from '../../../data/ticket.service';

@Component({
  selector: 'app-ticket-intake',
  standalone: true,
  imports: [ReactiveFormsModule],
  template: `
    <form [formGroup]="form" (ngSubmit)="submit()" aria-label="Support ticket form">
      <label>Title <input type="text" formControlName="title" /></label>
      <label>Email <input type="email" formControlName="email" /></label>
      <label>
        Priority
        <select formControlName="priority">
          <option value="low">Low</option>
          <option value="medium">Medium</option>
          <option value="high">High</option>
        </select>
      </label>
      <label>Message <textarea formControlName="message"></textarea></label>

      @if (form.hasError('submit')) {
        <p role="alert">Ticket could not be saved. Please try again.</p>
      }
      @if (savedTicket(); as ticket) {
        <p role="status">Saved ticket {{ ticket.id }}</p>
      }
      <button type="submit" [disabled]="isSubmitDisabled()">
        {{ saving() ? 'Saving...' : 'Create ticket' }}
      </button>
    </form>
  `,
})
export class TicketIntakeComponent {
  private readonly ticketService = inject(TicketService);
  readonly saving = signal(false);
  readonly savedTicket = signal<Ticket | null>(null);

  readonly form = new FormGroup({
    title: new FormControl('', { nonNullable: true, validators: [Validators.required, Validators.minLength(5)] }),
    email: new FormControl('', { nonNullable: true, validators: [Validators.required, Validators.email] }),
    priority: new FormControl<TicketPriority>('medium', { nonNullable: true }),
    message: new FormControl('', { nonNullable: true, validators: [Validators.required, Validators.minLength(20)] }),
  });

  readonly isSubmitDisabled = computed(() => this.form.invalid || this.saving());

  submit(): void {
    this.form.markAllAsTouched();
    this.form.setErrors(null);
    if (this.form.invalid) return;

    this.saving.set(true);
    this.ticketService.createTicket(this.form.getRawValue()).pipe(
      finalize(() => this.saving.set(false)),
    ).subscribe({
      next: (ticket) => {
        this.savedTicket.set(ticket);
        this.form.reset({ title: '', email: '', priority: 'medium', message: '' });
      },
      error: () => this.form.setErrors({ submit: true }),
    });
  }
}

Typische Stolperfallen sind die Mischung von ngModel und formControlName, ein nicht deaktivierter Submit-Button während des Speicherns und direkte Nutzung von form.value mit potenziell nullbaren Werten.

Praktische Use Cases

Erster Use Case: ein Backoffice-Formular. Der Prompt muss Felder, Validierungsregeln, Ladezustand, Erfolg und Fehler benennen.

Zweiter Use Case: HTTP-Aufrufe aus Legacy-Components in einen Service ziehen. Claude Code soll Typen, Service, UI-Trennung und HttpClient-Test liefern.

Dritter Use Case: Bugfix mit Regressionstest. Wenn ein API-Fehler den Button dauerhaft deaktiviert, liefern Sie Reproduktion, Erwartung und Testbefehl.

Vierter Use Case: schrittweise Migration zu Standalone Components. Begrenzen Sie die Änderung auf ein Feature-Verzeichnis und lassen Sie Routing und Provider stabil.

Tests und Review

HttpClient-Tests dürfen kein echtes Netzwerk verwenden.

import { TestBed } from '@angular/core/testing';
import { provideHttpClient } from '@angular/common/http';
import { provideHttpClientTesting, HttpTestingController } from '@angular/common/http/testing';
import { TicketService } from './ticket.service';

describe('TicketService', () => {
  let service: TicketService;
  let http: HttpTestingController;

  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [TicketService, provideHttpClient(), provideHttpClientTesting()],
    });
    service = TestBed.inject(TicketService);
    http = TestBed.inject(HttpTestingController);
  });

  afterEach(() => http.verify());

  it('creates a ticket through the API', () => {
    const draft = {
      title: 'Billing export is stuck',
      email: 'ops@example.com',
      priority: 'high' as const,
      message: 'The monthly billing export has not finished for two hours.',
    };

    service.createTicket(draft).subscribe((ticket) => expect(ticket.id).toBe('T-100'));
    const req = http.expectOne('/api/tickets');
    expect(req.request.method).toBe('POST');
    expect(req.request.body).toEqual(draft);
    req.flush({ ...draft, id: 'T-100', createdAt: '2026-06-02T09:00:00.000Z' });
  });
});

Für E2E nutzen Sie ng e2e, wenn das Workspace-Ziel existiert, oder Playwright, wenn dies Teamstandard ist. Prüfen Sie den echten Nutzerpfad: Seite öffnen, Felder ausfüllen, API kontrollieren, Erfolgsmeldung sehen.

Reviewe diesen Angular-Diff kritisch.
Prüfe Standalone imports/providers, nullable Werte in Reactive Forms,
doppeltes Absenden, Service/UI-Grenzen, HttpClient-Tests,
Unit/E2E-Abdeckung, any-Nutzung, unnötige subscriptions und Accessibility.
Gib Probleme mit Datei, Zeile und Priorität zurück.

Ergebnis und CTA

In einem kleinen Angular-Testprojekt führte ein vager Prompt zu ngModel-Mischung, UI-Text im Service und fehlenden Fehlerpfad-Tests. Mit klarer Aufteilung in Analyse, Service, Formular, HTTP-Test, E2E und Review war der Diff deutlich besser prüfbar. Für Teams lohnt es sich, diese Regeln in CLAUDE.md festzuhalten und über Claude Code Schulung und Beratung einen wiederholbaren Review-Prozess aufzubauen.

#Claude Code #Angular #TypeScript #frontend #enterprise
Kostenlos

Kostenloses PDF: Claude-Code-Cheatsheet

E-Mail eintragen und eine Seite mit Befehlen, Review-Gewohnheiten und sicheren Workflows herunterladen.

Wir schützen Ihre Daten und senden keinen Spam.

Masa

Über den Autor

Masa

Engineer für praktische Claude-Code-Workflows und Team-Einführung.