Blog>
Snippets

Asynchronous Validation using TanStack Form and Zod

Illustrate performing asynchronous validation in TanStack Form using Zod to check the uniqueness of a username against an API.
import { useForm } from '@tanstack/react-form';
import { zodValidator } from '@tanstack/zod-form-adapter';
import { z } from 'zod';
import axios from 'axios';
Imports useForm from TanStack React Form, zodValidator from TanStack Zod Form Adapter, Zod itself, and Axios for making HTTP requests.
const asyncUsernameValidator = async (username) => {
  try {
    const response = await axios.get(`/api/username/${username}`);
    return response.data.isAvailable ? true : new Error('Username is already taken');
  } catch (error) {
    return new Error('Failed to validate username');
  }
};
Defines an async function to validate the username against a server-side resource using Axios to make a get request. It expects an API endpoint that checks if the username is available and returns an object with a boolean property 'isAvailable'.
const schema = z.object({
  username: z.string().min(1, 'Username is required').refine(asyncUsernameValidator, 'Username must be unique')
});
Defines a Zod schema for form validation. Uses 'refine' method for asynchronous validation of the username field to ensure uniqueness according to the asyncUsernameValidator.
const form = useForm({
  validate: zodValidator(schema),
  onSubmit: async (values) => {
    console.log('Form Submitted:', values);
  },
});
Initializes the form with useForm hook from TanStack React Form, applying the Zod schema validator. Handles form submission with an onSubmit function.
const { Form, Field } = form;
return (
  <Form>
    <Field
      name="username"
      component="input"
      placeholder="Username"
    />
    <button type="submit">Submit</button>
  </Form>
);
Defines the JSX structure for rendering the form, using destructuring to access Form and Field components from the useForm instance. Includes an input field for username and a submit button.