You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
asyncfunctionfetchData(url){try{constresponse=awaitfetch(url);// ⚠️ fetch does NOT throw on 404/500 — check manually!if(!response.ok){thrownewError(`HTTP Error: ${response.status}`);}returnawaitresponse.json();}catch(error){if(errorinstanceofTypeError){console.error("Network error:",error);}else{console.error("API error:",error.message);}}}
Axios — Automatic Error Handling
asyncfunctionfetchData(url){try{constresponse=awaitaxios.get(url);returnresponse.data;}catch(error){if(error.response){// Server responded with error status (4xx, 5xx)console.error("Server error:",error.response.status);}elseif(error.request){// Request made but no response receivedconsole.error("No response from server");}else{console.error("Error:",error.message);}}}
// apiService.js — reusable for entire projectconstAPI_URL=process.env.REACT_APP_API_URL||"http://localhost:3000";exportconstapiCall=async(endpoint,options={})=>{try{constresponse=awaitfetch(`${API_URL}${endpoint}`,{headers: {"Content-Type": "application/json",
...options.headers},
...options});if(!response.ok){thrownewError(`API Error: ${response.status}`);}returnawaitresponse.json();}catch(error){console.error("API call failed:",error);throwerror;}};// Usage anywhere in the projectconstusers=awaitapiCall("/users");constpost=awaitapiCall("/posts",{method: "POST",body: JSON.stringify({title: "Hello"})});
10. Real World — User Management Class
classUserAPI{constructor(baseURL="https://jsonplaceholder.typicode.com"){this.baseURL=baseURL;}asyncgetAllUsers(){try{constresponse=awaitfetch(`${this.baseURL}/users`);if(!response.ok)thrownewError("Failed to fetch users");returnawaitresponse.json();}catch(error){console.error("Error:",error);}}asyncgetUser(userId){try{constresponse=awaitfetch(`${this.baseURL}/users/${userId}`);if(!response.ok)thrownewError("User not found");returnawaitresponse.json();}catch(error){console.error("Error:",error);}}asynccreateUser(userData){try{constresponse=awaitfetch(`${this.baseURL}/users`,{method: "POST",headers: {"Content-Type": "application/json"},body: JSON.stringify(userData)});if(!response.ok)thrownewError("Failed to create user");returnawaitresponse.json();}catch(error){console.error("Error:",error);}}asyncupdateUser(userId,userData){try{constresponse=awaitfetch(`${this.baseURL}/users/${userId}`,{method: "PUT",headers: {"Content-Type": "application/json"},body: JSON.stringify(userData)});if(!response.ok)thrownewError("Failed to update user");returnawaitresponse.json();}catch(error){console.error("Error:",error);}}asyncdeleteUser(userId){try{constresponse=awaitfetch(`${this.baseURL}/users/${userId}`,{method: "DELETE"});if(!response.ok)thrownewError("Failed to delete user");return{success: true};}catch(error){console.error("Error:",error);}}}// UsageconstuserAPI=newUserAPI();constusers=awaituserAPI.getAllUsers();constnewUser=awaituserAPI.createUser({name: "Sandhya",email: "s@example.com"});awaituserAPI.updateUser(1,{name: "Updated Name"});awaituserAPI.deleteUser(1);
11. Best Practices
// 1. Use environment variables for API URLsconstAPI_URL=process.env.REACT_APP_API_URL;// 2. Always handle loading and error statesasyncfunctionfetchUserData(userId){letisLoading=true;letdata=null;leterror=null;try{data=awaitfetch(`/api/users/${userId}`).then(r=>r.json());}catch(err){error=err;}finally{isLoading=false;}return{ isLoading, data, error };}// 3. Set request timeoutsconstfetchWithTimeout=(url,timeout=5000)=>{returnPromise.race([fetch(url),newPromise((_,reject)=>setTimeout(()=>reject(newError("Request timeout")),timeout))]);};// 4. Use proper headersconstheaders={"Content-Type": "application/json","Authorization": `Bearer ${token}`,"X-API-Key": process.env.API_KEY};// 5. Validate API responsesasyncfunctiongetUser(userId){try{constdata=awaitfetch(`/api/users/${userId}`).then(r=>r.json());if(!data.id||!data.name){thrownewError("Invalid user data received");}returndata;}catch(error){console.error("Error:",error);}}
12. Fetch API vs Axios — Comparison
Feature
Fetch API
Axios
Built-in
✅ Yes
❌ Needs installation
Syntax
Verbose
Concise
Error Handling
Manual response.ok check
Automatic on 4xx/5xx
Request Timeout
❌ No native support
✅ Built-in
Interceptors
❌ No
✅ Yes
JSON Auto-convert
❌ Need .json()
✅ Automatic
Bundle Size
Zero
Small (~13kb)
Best For
Simple projects
Complex applications
Key Takeaways
Use Fetch API for simple projects — no dependencies needed ✅
Use Axios for complex apps — interceptors, auto JSON, cleaner syntax ✅
Always use async/await over .then() chains — more readable
Fetch does NOT throw on 404/500 — always check response.ok manually
Always wrap API calls in try/catch — handle errors gracefully
Use environment variables for API URLs — never hardcode them
Create a reusable API service — avoid repeating fetch logic everywhere