From 6032e3533fa01cb722d750db13419406da344ae0 Mon Sep 17 00:00:00 2001 From: Kamal Wickramanayake Date: Wed, 1 Jul 2026 15:30:09 +0530 Subject: React sample apps: useEffect hook, Axios api calls --- react/06-api-calls/src/App.css | 0 react/06-api-calls/src/App.jsx | 19 +++++++++ react/06-api-calls/src/assets/hero.png | Bin 0 -> 13057 bytes react/06-api-calls/src/assets/react.svg | 1 + react/06-api-calls/src/assets/vite.svg | 1 + react/06-api-calls/src/components/PostList.jsx | 42 +++++++++++++++++++ react/06-api-calls/src/components/PostTable.jsx | 52 ++++++++++++++++++++++++ react/06-api-calls/src/index.css | 0 react/06-api-calls/src/main.jsx | 10 +++++ react/06-api-calls/src/services/api.js | 37 +++++++++++++++++ 10 files changed, 162 insertions(+) create mode 100644 react/06-api-calls/src/App.css create mode 100644 react/06-api-calls/src/App.jsx create mode 100644 react/06-api-calls/src/assets/hero.png create mode 100644 react/06-api-calls/src/assets/react.svg create mode 100644 react/06-api-calls/src/assets/vite.svg create mode 100644 react/06-api-calls/src/components/PostList.jsx create mode 100644 react/06-api-calls/src/components/PostTable.jsx create mode 100644 react/06-api-calls/src/index.css create mode 100644 react/06-api-calls/src/main.jsx create mode 100644 react/06-api-calls/src/services/api.js (limited to 'react/06-api-calls/src') diff --git a/react/06-api-calls/src/App.css b/react/06-api-calls/src/App.css new file mode 100644 index 0000000..e69de29 diff --git a/react/06-api-calls/src/App.jsx b/react/06-api-calls/src/App.jsx new file mode 100644 index 0000000..b5306f0 --- /dev/null +++ b/react/06-api-calls/src/App.jsx @@ -0,0 +1,19 @@ +import { useEffect, useState } from 'react' +import reactLogo from './assets/react.svg' +import viteLogo from './assets/vite.svg' +import heroImg from './assets/hero.png' +import './App.css' +import PostList from './components/PostList' +import PostTable from './components/PostTable' + +function App() { + + return ( + <> + + + + ) +} + +export default App diff --git a/react/06-api-calls/src/assets/hero.png b/react/06-api-calls/src/assets/hero.png new file mode 100644 index 0000000..02251f4 Binary files /dev/null and b/react/06-api-calls/src/assets/hero.png differ diff --git a/react/06-api-calls/src/assets/react.svg b/react/06-api-calls/src/assets/react.svg new file mode 100644 index 0000000..6c87de9 --- /dev/null +++ b/react/06-api-calls/src/assets/react.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/react/06-api-calls/src/assets/vite.svg b/react/06-api-calls/src/assets/vite.svg new file mode 100644 index 0000000..5101b67 --- /dev/null +++ b/react/06-api-calls/src/assets/vite.svg @@ -0,0 +1 @@ +Vite diff --git a/react/06-api-calls/src/components/PostList.jsx b/react/06-api-calls/src/components/PostList.jsx new file mode 100644 index 0000000..e31baef --- /dev/null +++ b/react/06-api-calls/src/components/PostList.jsx @@ -0,0 +1,42 @@ +import { useState, useEffect } from 'react' +import api from '../services/api' + +const PostList = () => { + const [posts, setPosts] = useState([]); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + + // Fetch data on component mount + useEffect(() => { + api + .get("/posts") // Replace with your actual API endpoint + .then((response) => { + setPosts(response.data); + setLoading(false); + }) + .catch((err) => { + setError(err.message); + setLoading(false); + }); + }, []); + + if (loading) return

Loading posts...

; + if (error) return

Error: {error}

; + + return ( +
+

Latest posts

+ + {/* 1. LIST VIEW */} +
    + {posts.map((post) => ( +
  • + {post.title} by {post.author} (ID: {post.id}) +
  • + ))} +
+
+ ); +} + +export default PostList \ No newline at end of file diff --git a/react/06-api-calls/src/components/PostTable.jsx b/react/06-api-calls/src/components/PostTable.jsx new file mode 100644 index 0000000..90e3589 --- /dev/null +++ b/react/06-api-calls/src/components/PostTable.jsx @@ -0,0 +1,52 @@ +import { useState, useEffect } from 'react' +import api from '../services/api' + +const PostTable = () => { + const [posts, setPosts] = useState([]); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + + // Fetch data on component mount + useEffect(() => { + api + .get("/posts") // Replace with your actual API endpoint + .then((response) => { + setPosts(response.data); + setLoading(false); + }) + .catch((err) => { + setError(err.message); + setLoading(false); + }); + }, []); + + if (loading) return

Loading posts...

; + if (error) return

Error: {error}

; + + return ( +
+

Latest posts

+ + + + + + + + + + + {posts.map((post) => ( + + + + + + ))} + +
IDTitleAuthor
{post.id}{post.title}{post.author}
+
+ ); +} + +export default PostTable \ No newline at end of file diff --git a/react/06-api-calls/src/index.css b/react/06-api-calls/src/index.css new file mode 100644 index 0000000..e69de29 diff --git a/react/06-api-calls/src/main.jsx b/react/06-api-calls/src/main.jsx new file mode 100644 index 0000000..b9a1a6d --- /dev/null +++ b/react/06-api-calls/src/main.jsx @@ -0,0 +1,10 @@ +import { StrictMode } from 'react' +import { createRoot } from 'react-dom/client' +import './index.css' +import App from './App.jsx' + +createRoot(document.getElementById('root')).render( + + + , +) diff --git a/react/06-api-calls/src/services/api.js b/react/06-api-calls/src/services/api.js new file mode 100644 index 0000000..215ee1b --- /dev/null +++ b/react/06-api-calls/src/services/api.js @@ -0,0 +1,37 @@ +import axios from 'axios'; + +const api = axios.create({ + baseURL: '/bff/api', // Example value: https://www.example.com + timeout: 30000, // 30 seconds + headers: { 'Content-Type': 'application/json' }, + withCredentials: true +}); + +// Request Interceptor (Optional: Add Authorization Headers) +/* +api.interceptors.request.use( + (request) => { + console.log("API Request:", request); + return request; + }, + (error) => Promise.reject(error) +); +*/ + +// Response Interceptor for Centralized Error Handling +api.interceptors.response.use( + (response) => { + return response; + }, + (error) => { + console.error("API ERROR:", error.response || error.message); + + if (window.confirm("A network error occured. Try reloading the page?")) { + window.location.href = "/bff/ui"; + } + + return Promise.reject(error); + } +); + +export default api; \ No newline at end of file -- cgit v1.2.3