import { useMutation, useQuery } from '@tanstack/react-query';
import { useEffect, useState } from 'react';
import {
addPetMutation,
getPetByIdOptions,
updatePetMutation,
} from './client/@tanstack/react-query.gen';
import { createClient } from './client/client';
import { PetSchema } from './client/schemas.gen';
import type { Pet } from './client/types.gen';
const localClient = createClient({
baseUrl: 'https://petstore3.swagger.io/api/v3',
headers: {
Authorization: 'Bearer <token_from_local_client>',
},
});
localClient.interceptors.request.use((request, options) => {
// Add authorization tokens to protected paths
if (options.url === '/pet/{petId}' && options.method === 'GET' && Math.random() < 0.5) {
request.headers.set('Authorization', 'Bearer <token_from_interceptor>');
}
return request;
});
function App() {
const [pet, setPet] = useState<Pet>();
const [petId, setPetId] = useState<number>();
const [isRequiredNameError, setIsRequiredNameError] = useState(false);
// Query with options
const { data, error } = useQuery({
...getPetByIdOptions({
client: localClient,
path: {
petId: petId!,
},
}),
enabled: Boolean(petId),
});
// Add pet mutation
const addPet = useMutation({
...addPetMutation(),
onError: (error) => {
console.log(error);
setIsRequiredNameError(false);
},
onSuccess: (data) => {
setPet(data);
setIsRequiredNameError(false);
},
});
// Update pet mutation
const updatePet = useMutation({
...updatePetMutation(),
onError: (error) => {
console.log(error);
},
onSuccess: (data) => {
setPet(data);
},
});
const onAddPet = async (formData: FormData) => {
// Form validation using schemas
if (PetSchema.required.includes('name') && !formData.get('name')) {
setIsRequiredNameError(true);
return;
}
addPet.mutate({
body: {
category: {
id: 0,
name: formData.get('category') as string,
},
id: 0,
name: formData.get('name') as string,
photoUrls: ['string'],
status: 'available',
tags: [{ id: 0, name: 'string' }],
},
});
};
const onGetPetById = async () => {
setPetId(Math.floor(Math.random() * 10 + 1));
};
const onUpdatePet = async () => {
updatePet.mutate({
body: {
category: { id: 0, name: 'Cats' },
id: 2,
name: 'Updated Kitty',
photoUrls: ['string'],
status: 'available',
tags: [{ id: 0, name: 'string' }],
},
headers: {
Authorization: 'Bearer <token_from_method>',
},
});
};
useEffect(() => {
if (error) {
console.log(error);
return;
}
setPet(data!);
}, [data, error]);
return (
<div>
<h1>@hey-api/openapi-ts 🤝 TanStack React Query</h1>
{pet && (
<div>
<h2>{pet.name}</h2>
<p>Category: {pet.category?.name ?? 'N/A'}</p>
</div>
)}
<button onClick={onGetPetById}>Get Random Pet</button>
<button onClick={onUpdatePet}>Update Pet</button>
<form onSubmit={(e) => {
e.preventDefault();
onAddPet(new FormData(e.currentTarget));
}}>
<input name="name" placeholder="Name" />
<input name="category" placeholder="Category" />
<button type="submit">Add Pet</button>
</form>
</div>
);
}
export default App;