Skip to content

Working with Forms ​

This guide covers how to work with forms using Flowfull Client.

Basic Form Handling ​

Flowfull Client doesn't include built-in form components, but it's easy to integrate with standard forms:

React Example ​

typescript
import { useState } from 'react';
import { api } from '../lib/api';

function CreateUserForm() {
  const [formData, setFormData] = useState({
    name: '',
    email: '',
    password: ''
  });
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState('');

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    setLoading(true);
    setError('');

    try {
      const user = await api.post('/users', formData);
      console.log('User created:', user);
      
      // Reset form
      setFormData({ name: '', email: '', password: '' });
      
      // Show success message or redirect
      alert('User created successfully!');
    } catch (err: any) {
      setError(err.message || 'Failed to create user');
    } finally {
      setLoading(false);
    }
  }

  function handleChange(e: React.ChangeEvent<HTMLInputElement>) {
    setFormData({
      ...formData,
      [e.target.name]: e.target.value
    });
  }

  return (
    <form onSubmit={handleSubmit}>
      <div>
        <input
          type="text"
          name="name"
          value={formData.name}
          onChange={handleChange}
          placeholder="Name"
          required
        />
      </div>
      <div>
        <input
          type="email"
          name="email"
          value={formData.email}
          onChange={handleChange}
          placeholder="Email"
          required
        />
      </div>
      <div>
        <input
          type="password"
          name="password"
          value={formData.password}
          onChange={handleChange}
          placeholder="Password"
          required
        />
      </div>
      <button type="submit" disabled={loading}>
        {loading ? 'Creating...' : 'Create User'}
      </button>
      {error && <div style={{ color: 'red' }}>{error}</div>}
    </form>
  );
}

Update Forms ​

typescript
import { useState, useEffect } from 'react';
import { api } from '../lib/api';

function EditUserForm({ userId }: { userId: string }) {
  const [formData, setFormData] = useState({
    name: '',
    email: ''
  });
  const [loading, setLoading] = useState(false);
  const [fetching, setFetching] = useState(true);

  useEffect(() => {
    // Fetch user data
    async function fetchUser() {
      try {
        const user = await api.get(`/users/${userId}`);
        setFormData({
          name: user.name,
          email: user.email
        });
      } catch (error) {
        console.error('Error fetching user:', error);
      } finally {
        setFetching(false);
      }
    }
    
    fetchUser();
  }, [userId]);

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    setLoading(true);

    try {
      const updated = await api.put(`/users/${userId}`, formData);
      console.log('User updated:', updated);
      alert('User updated successfully!');
    } catch (error: any) {
      alert(error.message || 'Failed to update user');
    } finally {
      setLoading(false);
    }
  }

  if (fetching) return <div>Loading...</div>;

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        value={formData.name}
        onChange={(e) => setFormData({ ...formData, name: e.target.value })}
        placeholder="Name"
      />
      <input
        type="email"
        value={formData.email}
        onChange={(e) => setFormData({ ...formData, email: e.target.value })}
        placeholder="Email"
      />
      <button type="submit" disabled={loading}>
        {loading ? 'Updating...' : 'Update User'}
      </button>
    </form>
  );
}

File Upload Forms ​

typescript
function UploadForm() {
  const [file, setFile] = useState<File | null>(null);
  const [loading, setLoading] = useState(false);

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    if (!file) return;

    setLoading(true);

    try {
      const formData = new FormData();
      formData.append('file', file);
      formData.append('name', 'My File');

      const response = await api.post('/upload', formData);
      console.log('File uploaded:', response);
      alert('File uploaded successfully!');
    } catch (error: any) {
      alert(error.message || 'Upload failed');
    } finally {
      setLoading(false);
    }
  }

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="file"
        onChange={(e) => setFile(e.target.files?.[0] || null)}
      />
      <button type="submit" disabled={!file || loading}>
        {loading ? 'Uploading...' : 'Upload'}
      </button>
    </form>
  );
}

Next Steps ​