# Fetch to Axios Migration Guide This document outlines the pattern for migrating fetch API calls to axios in our codebase. ## Why migrate from fetch to axios? Axios provides several advantages over the native fetch API: - Automatic JSON data transformation - Better error handling - Request/response interceptors - Simpler syntax for common operations - Consistent error objects ## Migration Pattern ### 1. Import axios First, add the axios import to your file: ```typescript import axios from 'axios'; ``` ### 2. Replace GET requests **Before (with fetch):** ```typescript const response = await fetch(url, { method: 'GET', headers: { 'Content-Type': 'application/json', // other headers... }, mode: 'cors', credentials: 'include' // or 'omit' }); if (!response.ok) { const errorText = await response.text(); throw new Error(`Failed: ${response.status} ${response.statusText}`); } const data = await response.json(); return data; ``` **After (with axios):** ```typescript const response = await axios.get(url, { headers: { 'Content-Type': 'application/json', // other headers... }, withCredentials: true // replaces credentials: 'include' // Note: 'mode: cors' is not needed with axios }); // No need to check response.ok - axios throws on error status codes // No need to parse JSON - axios does this automatically return response.data; ``` ### 3. Replace POST requests **Before (with fetch):** ```typescript const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', // other headers... }, body: JSON.stringify(data), mode: 'cors', credentials: 'include' // or 'omit' }); if (!response.ok) { throw new Error(`Failed: ${response.status} ${response.statusText}`); } const responseData = await response.json(); return responseData; ``` **After (with axios):** ```typescript const response = await axios.post(url, data, { headers: { 'Content-Type': 'application/json', // other headers... }, withCredentials: true // if needed }); return response.data; ``` ### 4. Replace PUT requests **Before (with fetch):** ```typescript const response = await fetch(url, { method: 'PUT', headers: { 'Content-Type': 'application/json', // other headers... }, body: JSON.stringify(data), mode: 'cors', credentials: 'include' // or 'omit' }); if (!response.ok) { throw new Error(`Failed: ${response.status} ${response.statusText}`); } const responseData = await response.json(); return responseData; ``` **After (with axios):** ```typescript const response = await axios.put(url, data, { headers: { 'Content-Type': 'application/json', // other headers... }, withCredentials: true // if needed }); return response.data; ``` ### 5. Replace DELETE requests **Before (with fetch):** ```typescript const response = await fetch(url, { method: 'DELETE', headers: { 'Content-Type': 'application/json', // other headers... }, mode: 'cors', credentials: 'include' // or 'omit' }); if (!response.ok) { throw new Error(`Failed: ${response.status} ${response.statusText}`); } // Handle response as needed ``` **After (with axios):** ```typescript const response = await axios.delete(url, { headers: { 'Content-Type': 'application/json', // other headers... }, withCredentials: true // if needed }); // response.data is already parsed if JSON was returned ``` ### 6. Error Handling **Before (with fetch):** ```typescript try { const response = await fetch(url); if (!response.ok) { const errorText = await response.text(); console.error(`API error: ${response.status} ${response.statusText}`, errorText); throw new Error(`Failed: ${response.status} ${response.statusText}`); } const data = await response.json(); return data; } catch (error) { console.error('Request failed:', error); throw error; } ``` **After (with axios):** ```typescript try { const response = await axios.get(url); return response.data; } catch (error) { if (axios.isAxiosError(error)) { console.error('API error:', error.message); console.error('Status:', error.response?.status); console.error('Data:', error.response?.data); throw new Error(`API Error: ${error.response?.status} ${error.message}`); } console.error('Request failed:', error); throw error; } ``` ## Common Patterns by File Type ### Service Files For service files, follow this general pattern: ```typescript import axios from 'axios'; import { API_BASE_URL } from '@/config'; export const exampleService = { getAll: async () => { try { const response = await axios.get(`${API_BASE_URL}/api/resource`, { headers: { 'Content-Type': 'application/json', }, withCredentials: false }); return response.data; } catch (error) { console.error('Error:', error); return []; // or throw error depending on your error handling strategy } }, getById: async (id) => { try { const response = await axios.get(`${API_BASE_URL}/api/resource/${id}`); return response.data; } catch (error) { console.error(`Error fetching resource ${id}:`, error); throw error; } }, create: async (data) => { try { const response = await axios.post(`${API_BASE_URL}/api/resource`, data); return response.data; } catch (error) { console.error('Error creating resource:', error); throw error; } } // etc. }; ``` ### Component Files For component files, integrate axios calls as follows: ```typescript import axios from 'axios'; import { API_BASE_URL } from '@/config'; const YourComponent = () => { useEffect(() => { const fetchData = async () => { try { const response = await axios.get(`${API_BASE_URL}/api/resource`); setData(response.data); } catch (error) { console.error('Error fetching data:', error); setError('Failed to load data'); } finally { setLoading(false); } }; fetchData(); }, []); // rest of component }; ``` ## Remaining Files to Update Based on our analysis, these files need to be updated: - src/pages/project-detail.tsx - src/pages/project-edit.tsx - src/pages/projects.tsx - src/components/appraisal/AppraisalForm.tsx - src/pages/appraisal/assessment-areas.tsx - src/utils/create-indicators.js - src/pages/appraisal/competencies.tsx - src/pages/appraisal/cycles.tsx - src/pages/appraisal/hr-remarks.tsx - src/pages/appraisal/management-remarks.tsx - src/pages/appraisal/manager-dashboard.tsx Follow the patterns in this guide to update these files.