Skip to main content

API Integration — Fetching from .NET Web API

Level: Beginner

ℹ️ What You'll Learn
  • Using fetch API to call .NET Web API endpoints
  • Axios as alternative to fetch with better DX
  • async/await for clean async code
  • Error handling for network and API failures
  • Authentication headers (JWT, bearer tokens)
  • Loading and error states while fetching
  • Pagination and filtering API responses
  • Integrating with SMS student, fee, attendance APIs

Why This Matters

API Integration — Fetching from .NET Web API is part of building maintainable React applications. You will use it when creating student dashboards, forms, tables, API-connected screens, routing flows, and reusable UI components.

React frontends need backend data. You've built the ASP.NET Web API; now consume it from React.

The Problem

Beginners often write React code that works for a small demo but becomes difficult when data, forms, API calls, and reusable components grow. This lesson explains API Integration — Fetching from .NET Web API in a way that helps you build predictable UI for real .NET Web API projects.

Basic Fetch Pattern

function StudentList() {
const [students, setStudents] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);

useEffect(() => {
const fetchStudents = async () => {
try {
const response = await fetch('http://localhost:5000/api/students');
if (!response.ok) throw new Error('Failed to fetch');
const data = await response.json();
setStudents(data);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
};

fetchStudents();
}, []);

if (loading) return <p>Loading...</p>;
if (error) return <p>Error: {error}</p>;

return (
<ul>
{students.map(s => (
<li key={s.id}>{s.name}</li>
))}
</ul>
);
}

GET Request

// Fetch one student
useEffect(() => {
fetch(`http://localhost:5000/api/students/${studentId}`)
.then(r => r.json())
.then(data => setStudent(data));
}, [studentId]);

// With query parameters
const params = new URLSearchParams({
className: '10',
status: 'Active'
});

fetch(`http://localhost:5000/api/students?${params}`)
.then(r => r.json())
.then(data => setStudents(data));

POST Request (Create)

function CreateStudent() {
const [formData, setFormData] = useState({
name: '',
email: '',
className: '10'
});

const handleSubmit = async (e) => {
e.preventDefault();

try {
const response = await fetch('http://localhost:5000/api/students', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(formData)
});

if (!response.ok) throw new Error('Failed to create');

const newStudent = await response.json();
console.log('Created:', newStudent);
setFormData({ name: '', email: '', className: '10' });
} catch (err) {
console.error(err);
}
};

return (
<form onSubmit={handleSubmit}>
<input
value={formData.name}
onChange={e => setFormData({...formData, name: e.target.value})}
placeholder="Name"
/>
<button type="submit">Create</button>
</form>
);
}

PUT Request (Update)

function UpdateStudent({ student }) {
const [formData, setFormData] = useState(student);

const handleSubmit = async (e) => {
e.preventDefault();

try {
const response = await fetch(
`http://localhost:5000/api/students/${student.id}`,
{
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(formData)
}
);

if (!response.ok) throw new Error('Failed to update');

const updated = await response.json();
console.log('Updated:', updated);
} catch (err) {
console.error(err);
}
};

return (
<form onSubmit={handleSubmit}>
<input
value={formData.name}
onChange={e => setFormData({...formData, name: e.target.value})}
/>
<button type="submit">Save</button>
</form>
);
}

DELETE Request

function DeleteStudent({ studentId, onDelete }) {
const handleDelete = async () => {
if (!window.confirm('Are you sure?')) return;

try {
const response = await fetch(
`http://localhost:5000/api/students/${studentId}`,
{ method: 'DELETE' }
);

if (!response.ok) throw new Error('Failed to delete');

onDelete(studentId);
} catch (err) {
console.error(err);
}
};

return <button onClick={handleDelete}>Delete</button>;
}

API Service (Reusable)

Instead of fetch() everywhere, create an API service:

// api/studentService.js
const API_BASE = 'http://localhost:5000/api';

const studentService = {
getAll: async () => {
const response = await fetch(`${API_BASE}/students`);
if (!response.ok) throw new Error('Failed to fetch students');
return response.json();
},

getById: async (id) => {
const response = await fetch(`${API_BASE}/students/${id}`);
if (!response.ok) throw new Error('Student not found');
return response.json();
},

create: async (data) => {
const response = await fetch(`${API_BASE}/students`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
if (!response.ok) throw new Error('Failed to create');
return response.json();
},

update: async (id, data) => {
const response = await fetch(`${API_BASE}/students/${id}`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
if (!response.ok) throw new Error('Failed to update');
return response.json();
},

delete: async (id) => {
const response = await fetch(`${API_BASE}/students/${id}`, {
method: 'DELETE'
});
if (!response.ok) throw new Error('Failed to delete');
return response.json();
}
};

export default studentService;

Usage:

import studentService from './api/studentService';

function StudentList() {
const [students, setStudents] = useState([]);

useEffect(() => {
studentService.getAll()
.then(data => setStudents(data))
.catch(err => console.error(err));
}, []);

return (
<ul>
{students.map(s => (
<li key={s.id}>{s.name}</li>
))}
</ul>
);
}

Authentication (JWT Tokens)

// Store token in localStorage after login
localStorage.setItem('token', jwtToken);

// Include in API requests
const studentService = {
getAll: async () => {
const token = localStorage.getItem('token');
const response = await fetch('http://localhost:5000/api/students', {
headers: {
'Authorization': `Bearer ${token}`
}
});
return response.json();
}
};

Environment Variables

Create .env file:

REACT_APP_API_BASE=http://localhost:5000/api

Use in code:

const API_BASE = process.env.REACT_APP_API_BASE;

const response = await fetch(`${API_BASE}/students`);

CORS Issues

If frontend and backend are on different ports, you'll get CORS errors. Configure in ASP.NET:

// Program.cs
var builder = WebApplicationBuilder.CreateBuilder(args);

builder.Services.AddCors(options =>
{
options.AddDefaultPolicy(policy =>
{
policy.WithOrigins("http://localhost:3000")
.AllowAnyMethod()
.AllowAnyHeader();
});
});

var app = builder.Build();
app.UseCors();

Real Example: Student Management CRUD

import studentService from './api/studentService';

function StudentManagement() {
const [students, setStudents] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);

useEffect(() => {
loadStudents();
}, []);

const loadStudents = async () => {
try {
setLoading(true);
const data = await studentService.getAll();
setStudents(data);
setError(null);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
};

const handleCreate = async (newStudent) => {
try {
const created = await studentService.create(newStudent);
setStudents([...students, created]);
} catch (err) {
setError(err.message);
}
};

const handleDelete = async (id) => {
try {
await studentService.delete(id);
setStudents(students.filter(s => s.id !== id));
} catch (err) {
setError(err.message);
}
};

if (loading) return <p>Loading...</p>;

return (
<div>
{error && <p className="error">{error}</p>}
<CreateStudentForm onCreate={handleCreate} />
<StudentList
students={students}
onDelete={handleDelete}
/>
</div>
);
}

Key Takeaways

  • Use fetch or axios for API calls
  • Create reusable API services
  • Handle errors and loading states
  • Store API base URL in env variables
  • Configure CORS on backend
  • Next: Routing for multiple pages
⚠️ API Mistakes
  1. No error handling — App crashes on bad response
  2. Hardcoded URLs — Can't change between dev/prod
  3. No loading state — UI looks broken
  4. Not handling CORS — Requests fail mysteriously
💡 Using Axios

Axios simplifies API calls:

import axios from 'axios';

const response = await axios.get('/api/students');
await axios.post('/api/students', data);
await axios.put(`/api/students/${id}`, data);
await axios.delete(`/api/students/${id}`);
🤖Use AI to Learn Faster

Use ChatGPT, Claude, or Copilot to go deeper on API Integration. Try these prompts:

  • "What's the difference between fetch and axios?"
  • "Why should you create an API service instead of using fetch directly?"
  • "How do you handle authentication tokens in API requests?"
  • "Quiz me on API integration"

💡 Tip: After reading this article, paste your own code into AI and ask "What could go wrong here and why?" — fastest way to find edge cases and deepen understanding.

Quick Definitions

  • API Integration — Fetching from .NET Web API - The main React concept explained in this lesson.
  • Component - A reusable function that returns UI.
  • Props/state/effects - Core React ideas used to pass data, remember data, and run side effects.
  • Real project usage - How this appears in forms, dashboards, routes, and API-connected pages.

Common Mistakes

  • Copying React code without understanding data flow
  • Mutating arrays or objects directly instead of creating new values
  • Forgetting keys, dependencies, loading states, or error states where needed
  • Putting too much logic in one component
  • Not testing the screen with realistic School Management System data

Practice Task

Create a small React example using API Integration — Fetching from .NET Web API. Keep it focused on one School Management System screen.

Suggested practice:

  1. Build a small component or page for students, attendance, marks, or fees.
  2. Pass realistic data into the component.
  3. Add one success state and one empty/error state where relevant.
  4. Explain the data flow in your own words.
  5. Rebuild the same example once without looking at the article.

Quick Revision

QuestionAnswer
What is the main idea?Understand and apply API Integration — Fetching from .NET Web API in React.
Where is it used?Student dashboards, forms, tables, routes, and API-connected screens.
What should beginners focus on?Clear components, predictable data flow, and small examples.
What is the best debugging habit?Check props, state, render output, and browser console step by step.
🎯 How would you explain API Integration — Fetching from .NET Web API in an interview?

API Integration — Fetching from .NET Web API is a React concept used to build clear, reusable, and predictable user interfaces. I would explain the problem it solves, show a small component example, and mention a common mistake beginners should avoid.

🎯 Where is this used in a real React project?

It is used in screens like student lists, admission forms, attendance dashboards, marks reports, routing pages, and API-connected admin panels.

Next Article

Routing — Multiple Pages ->

nexcoding.in