Magento 2 Experten — Hyvä Theme, Tailwind CSS & SEO aus einer Hand ›

Validierungsfehler im Formular anzeigen

Validierungsfehler im Formular anzeigen

~15 Min. Lesezeit Zuletzt aktualisiert am 8. August 2026

Das violations-Array aus Kapitel 20 landet BISHER im generischen isError-Zustand von Kapitel 78 – dieses Kapitel verbindet es MIT den EINZELNEN Formularfeldern.

Den Fehler-Typ definieren

src/types/error.ts
export interface Violation {
  propertyPath: string;
  message: string;
}

export interface ApiErrorResponse {
  violations?: Violation[];
}

Die violations aus dem axios-Fehler extrahieren

src/hooks/useCreateProject.ts
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { isAxiosError } from 'axios';
import { apiClient } from '../api/client';
import type { Project } from '../types/project';
import type { ApiErrorResponse, Violation } from '../types/error';

interface CreateProjectInput {
  name: string;
  description?: string;
}

export function useCreateProject() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async (input: CreateProjectInput) => {
      const response = await apiClient.post<Project>('/projects', input);

      return response.data;
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['projects'] });
    },
  });
}

export function extractViolations(error: unknown): Violation[] {
  if (isAxiosError<ApiErrorResponse>(error) && error.response?.data.violations) {
    return error.response.data.violations;
  }

  return [];
}

isAxiosError aus axios selbst ist ein TYPE-GUARD, der TypeScript BEWEIST, dass error die erwartete response.data-Struktur hat – OHNE diesen Guard würde TypeScript error als unknown behandeln und JEDEN Feldzugriff VERWEIGERN.

Das Formular um Fehleranzeige ergänzen

src/components/CreateProjectForm.tsx
import { useState, type FormEvent } from 'react';
import { useCreateProject, extractViolations } from '../hooks/useCreateProject';

function CreateProjectForm() {
  const [name, setName] = useState('');
  const createProject = useCreateProject();
  const violations = createProject.isError
    ? extractViolations(createProject.error)
    : [];

  function fieldError(field: string): string | undefined {
    return violations.find((v) => v.propertyPath === field)?.message;
  }

  function handleSubmit(event: FormEvent) {
    event.preventDefault();
    createProject.mutate({ name }, { onSuccess: () => setName('') });
  }

  return (
    <form onSubmit={handleSubmit}>
      <input value={name} onChange={(e) => setName(e.target.value)} />
      {fieldError('name') && <p className="error">{fieldError('name')}</p>}
      <button type="submit" disabled={createProject.isPending}>
        Projekt erstellen
      </button>
    </form>
  );
}

export default CreateProjectForm;

fieldError('name') sucht GEZIELT nach EINER Violation mit propertyPath === 'name' – GENAU der Mechanismus, den Kapitel 20 bereits ANKÜNDIGTE: propertyPath macht die FELDGENAUE Zuordnung erst MÖGLICH.

Achtung: #[UniqueProjectName] aus Kapitel 26 liefert SEINE Meldung EBENFALLS mit propertyPath: 'name' – das Formular zeigt EIGENE Validierungs-Constraints und EIGENE Business-Regeln (Eindeutigkeit) im GLEICHEN UI-Element an, OHNE dass das Frontend zwischen BEIDEN unterscheiden müsste.

Tipp: React Hook Form (in dieser Schulung BEWUSST NICHT eingesetzt, um die GRUNDMECHANIK ohne zusätzliche Bibliothek zu zeigen) würde GENAU DIESEN fieldError-Mechanismus über setError(propertyPath, { message }) NOCH ergonomischer gestalten, OHNE das zugrunde liegende Prinzip zu ändern.