FST_React_Angular
FST_React_Angular
// ClassComponent.js
import React from 'react';
// App.js
import React from 'react';
import FunctionComponent from './FunctionComponent';
import ClassComponent from './ClassComponent';
✅ Example Flow:
1. User types “Alchemist” in the React search bar.
2. React calls GET /api/books?title=alchemist.
3. Express (Node.js) receives the request, queries MongoDB.
4. MongoDB returns matching books to Express, which sends
them back to React.
5. React displays the results.
6. User clicks “Request to Borrow” → React sends POST
/api/requests.
7. Express saves the request in MongoDB and confirms to the
user.
const products = [
{ title: 'Cabbage', id: 1 },
{ title: 'Garlic', id: 2 },
{ title: 'Apple', id: 3 },
];
Inside your component, use the map() function to transform an
array of products into an array of
<li> items:
const listItems = products.map(product =>
<li key={product.id}>
{product.title}
</li>
);
return (
<ul>{listItems}</ul>
);
Notice how <li> has a key attribute. For each item in a list, you
should pass a string or a number
that uniquely identifies that item among its siblings. Usually, a key
should be coming from your
data, such as a database ID. React uses your keys to know what
happened if you later insert, delete,
or reorder the items.
function markComplete(id) {
const updatedTasks = tasks.map(task =>
task.id === id ? { ...task, completed: true } : task
);
setTasks(updatedTasks);
}
return (
<div>
<h2>Task List</h2>
<ul>
{tasks.map(task => (
<li key={task.id}>
{task.title} - {task.completed ? '✅ Done' : '❌ Not Done'}
<button onClick={() => markComplete(task.id)}>Mark
Done</button>
</li>
))}
</ul>
</div>
);
}
🔍 Line-by-line Explanation
Line 1
js
CopyEdit
import { useState } from 'react';
This imports the useState hook from React so we can use
state to store and update the task list.
Line 3
js
CopyEdit
export default function TaskList() {
Defines a functional React component named TaskList.
Lines 4–8
js
CopyEdit
const [tasks, setTasks] = useState([
{ id: 1, title: 'Buy groceries', completed: false },
{ id: 2, title: 'Do homework', completed: false },
{ id: 3, title: 'Read a book', completed: false },
]);
tasks is the state variable holding the array of tasks.
setTasks is the function to update that state.
useState(...) sets the initial value of tasks as an array of three
task objects.
Lines 10–14
js
CopyEdit
function markComplete(id) {
const updatedTasks = tasks.map(task =>
task.id === id ? { ...task, completed: true } : task
);
setTasks(updatedTasks);
}
Defines a function called markComplete, which takes the id of
a task.
.map() goes through each task in the array:
o If the task.id matches the id we passed, it returns a new
object with completed: true.
o If it doesn't match, it returns the task as-is.
setTasks(updatedTasks) updates the state with the new task
list.
Lines 16–27
js
CopyEdit
return (
<div>
<h2>Task List</h2>
<ul>
{tasks.map(task => (
<li key={task.id}>
{task.title} - {task.completed ? '✅ Done' : '❌ Not Done'}
<button onClick={() => markComplete(task.id)}>Mark
Done</button>
</li>
))}
</ul>
</div>
);
This is the UI (JSX) returned by the component.
<ul> displays the list of tasks.
{tasks.map(...)} loops over each task and returns a <li>
element for each.
o key={task.id} helps React track items.
o {task.title} shows the task name.
o {task.completed ? '✅ Done' : '❌ Not Done'} shows whether
it's done.
o <button onClick={...}> calls markComplete(task.id)
when clicked.
✅ Summary:
This component maintains a list of tasks in state.
It displays each task with a status and a button.
Clicking the button updates that task’s completed field.
React automatically re-renders the UI when the state
updates.
return (
<div>
<h2>Item List</h2>
<input
type="text"
value={itemInput}
onChange={handleInputChange} // Update input field
placeholder="Enter an item"
/>
<button onClick={handleAddItem}>Add Item</button> {/*
Trigger handleAddItem on click */}
<ul>
{items.map((item, index) => (
<li key={index}>{item}</li> // Display each item in the list
))}
</ul>
</div>
);
}
Explanation Line by Line:
import React, { useState } from 'react';
Import React and the useState hook to manage the state in the
functional component.
Define the ItemList component, which will handle the list of items.
Define the items state, which will store the array of items that the
user adds. Initially, it's an empty array.
Define the itemInput state to store the current value in the input
field where the user types a new item.
Define the handleAddItem function that will be called when the user
clicks the "Add Item" button. This function will add the item in the
input field to the items list.
if (itemInput.trim()) {
Check if the input field is not empty (ignoring any spaces). This
prevents adding empty or whitespace-only items to the list.
setItems([...items, itemInput]);
Update the items array by adding the new item (itemInput) to the
list using the spread operator (...items) to retain the existing items
in the array.
setItemInput('');
setItemInput(event.target.value);
Set the itemInput state to the current value of the input field
(event.target.value).
return (...)
Return the JSX structure of the component that renders the UI for
this component.
Render an input field where the user can type the new item. The
value of this input is controlled by the itemInput state, and any
change in the input field triggers the handleInputChange function.
diff
Copy
Edit
- Buy groceries
Type "Do homework" in the input field, and click "Add Item":
diff
Copy
Edit
- Buy groceries
- Do homework
function App() {
const [isLoggedIn, setIsLoggedIn] = useState(false);
return (
<div>
<h1>Conditional Rendering Example</h1>
{isLoggedIn ? (
<p>Welcome back, User!</p>
):(
<p>Please log in to continue.</p>
)}
<button onClick={() => setIsLoggedIn(!isLoggedIn)}>
{isLoggedIn ? 'Log Out' : 'Log In'}
</button>
</div>
);
}
🧠 Line-by-Line Explanation
Line 1:
js
CopyEdit
import React, { useState } from 'react';
Imports React and the useState hook, which is used to manage
state in functional components.
Line 3:
js
CopyEdit
function App() {
Declares a React functional component named App.
Line 4:
js
CopyEdit
const [isLoggedIn, setIsLoggedIn] = useState(false);
Creates a state variable isLoggedIn with the default value
false.
setIsLoggedIn is a function used to change the value of
isLoggedIn.
Line 6–16:
js
CopyEdit
return (
<div>
...
</div>
);
Returns JSX (HTML-like syntax in React) that defines the
structure of what will be shown in the browser.
Line 7:
js
CopyEdit
<h1>Conditional Rendering Example</h1>
Displays a title for the page.
Lines 9–13:
js
CopyEdit
{isLoggedIn ? (
<p>Welcome back, User!</p>
):(
<p>Please log in to continue.</p>
)}
This is the conditional rendering part.
If isLoggedIn is true, it shows the message "Welcome back,
User!"
If isLoggedIn is false, it shows "Please log in to continue."
Line 15:
js
CopyEdit
<button onClick={() => setIsLoggedIn(!isLoggedIn)}>
A button that toggles the login state when clicked.
!isLoggedIn flips the current value (true becomes false, and
vice versa).
Line 16:
js
CopyEdit
{isLoggedIn ? 'Log Out' : 'Log In'}
Button text changes based on the login status.
Shows "Log Out" if user is logged in, otherwise shows "Log In".
Line 20:
js
CopyEdit
export default App;
Exports the App component so it can be used in other parts of
the application.
8. Create a project using React Router with two pages, Home and
Films containing list of directors and the films.
Ans: App.js
jsx
CopyEdit
import { BrowserRouter, Routes, Route, Link } from 'react-router-
dom';
import Home from './Home';
import Films from './Films';
export default function App() {
return (
<BrowserRouter>
<nav>
<Link to="/">Home</Link> | <Link to="/films">Films</Link>
</nav>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/films" element={<Films />} />
</Routes>
</BrowserRouter>
);
}
Home.js
jsx
CopyEdit
export default function Home() {
return (
<div>
<h1>Welcome to Movie World</h1>
<p>Click on Films to explore directors and their works.</p>
</div>
);
}
Films.js
jsx
CopyEdit
export default function Films() {
const data = [
{ director: 'Christopher Nolan', films: ['Inception', 'Interstellar'] },
{ director: 'Steven Spielberg', films: ['E.T.', 'Jaws'] },
];
return (
<div>
<h1>Directors and Their Films</h1>
<ul>
{data.map((item, index) => (
<li key={index}>
<strong>{item.director}</strong>
<ul>
{item.films.map((film, i) => (
<li key={i}>{film}</li>
))}
</ul>
</li>
))}
</ul>
</div>
);
}
const root =
ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);
function GroceryList() {
const [searchTerm, setSearchTerm] = useState('');
const groceries = [
{ name: 'Apples', price: 1.5, quantity: 5 },
{ name: 'Bananas', price: 0.5, quantity: 10 },
{ name: 'Carrots', price: 0.8, quantity: 8 },
{ name: 'Milk', price: 2.0, quantity: 2 },
];
return (
<div>
<h2>Grocery List</h2>
<input
type="text"
placeholder="Search item"
value={searchTerm}
onChange={e => setSearchTerm(e.target.value)}
/>
<ul>
{filteredItems.map((item, index) => (
<GroceryItem
key={index}
name={item.name}
price={item.price}
quantity={item.quantity}
/>
))}
</ul>
</div>
);
}
return (
<div>
<h2>Cart</h2>
<ul>
{cartItems.map((item, index) => (
<li key={index}>
{item.name} - ${item.price} × {item.quantity}
<button onClick={() =>
onIncrease(item.name)}>+</button>
<button onClick={() =>
onDecrease(item.name)}>-</button>
</li>
))}
</ul>
<h3>Total: ${total.toFixed(2)}</h3>
</div>
);
}
function GroceryApp() {
const items = [
{ name: 'Apples', price: 1.5 },
{ name: 'Bananas', price: 0.5 },
{ name: 'Carrots', price: 0.8 },
];
function addToCart(item) {
const found = cart.find(i => i.name === item.name);
if (found) {
const updated = cart.map(i =>
i.name === item.name ? { ...i, quantity: i.quantity + 1 } : i
);
setCart(updated);
} else {
setCart([...cart, { ...item, quantity: 1 }]);
}
}
function increaseQty(name) {
setCart(
cart.map(item =>
item.name === name ? { ...item, quantity: item.quantity +
1 } : item
)
);
}
function decreaseQty(name) {
setCart(
cart
.map(item =>
item.name === name
? { ...item, quantity: item.quantity - 1 }
: item
)
.filter(item => item.quantity > 0)
);
}
return (
<div>
<h1>Grocery Store</h1>
<ul>
{items.map((item, index) => (
<GroceryItem key={index} item={item}
onAddToCart={addToCart} />
))}
</ul>
<Cart
cartItems={cart}
onIncrease={increaseQty}
onDecrease={decreaseQty}
/>
</div>
);
}
Task: Simulate fetching grocery item data from an API (you can use
a local JSON file or a mock API). Display the fetched data in the
GroceryList component. Implement a loading state while the data is
being fetched and handle potential errors.
Concepts: Asynchronous operations (fetch or axios), useEffect hook
for side effects, handling loading states, error handling.
import React, { useState, useEffect } from 'react';
function GroceryList() {
const [items, setItems] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
// Simulating fetch from an API or local JSON file
fetch('https://mocki.io/v1/49aeb7f6-2ae4-4c68-bc7a-
7e23b9778124') // <-- Example mock API
.then(response => {
if (!response.ok) throw new Error('Network response was not
ok');
return response.json();
})
.then(data => {
setItems(data);
setLoading(false);
})
.catch(err => {
setError('Failed to fetch items');
setLoading(false);
});
}, []); // Runs once on component mount
return (
<div>
<h2>Available Grocery Items</h2>
<ul>
{items.map((item, index) => (
<li key={index}>
{item.name} - ${item.price}
</li>
))}
</ul>
</div>
);
}
function GroceryForm() {
const [items, setItems] = useState([]);
const [name, setName] = useState('');
const [price, setPrice] = useState('');
const [quantity, setQuantity] = useState('');
const [error, setError] = useState('');
function handleSubmit(e) {
e.preventDefault();
if (isNaN(price) || isNaN(quantity)) {
setError('Price and Quantity must be numbers');
return;
}
const newItem = {
name,
price: parseFloat(price),
quantity: parseInt(quantity),
};
setItems([...items, newItem]);
// Clear form
setName('');
setPrice('');
setQuantity('');
setError('');
}
return (
<div>
<h2>Add Grocery Item</h2>
<form onSubmit={handleSubmit}>
<input
type="text"
placeholder="Item Name"
value={name}
onChange={e => setName(e.target.value)}
/>
<input
type="text"
placeholder="Price"
value={price}
onChange={e => setPrice(e.target.value)}
/>
<input
type="text"
placeholder="Quantity"
value={quantity}
onChange={e => setQuantity(e.target.value)}
/>
<button type="submit">Add Item</button>
</form>
{error && <p style={{ color: 'red' }}>{error}</p>}
<ul>
{items.map((item, index) => (
<li key={index}>
{item.name} - ${item.price} x {item.quantity}
</li>
))}
</ul>
</div>
);
}
Task: Use React Router to create different views for the application.
Implement routes for the grocery list, the cart, and a "New Item"
form. Create navigation links to switch between these views.
Concepts: React Router (installation and usage), route definition,
navigation using Link components, organizing application views.
📁 App.js
jsx
CopyEdit
import React from 'react';
import { BrowserRouter, Routes, Route, Link } from 'react-
router-dom';
import GroceryList from './GroceryList';
import Cart from './Cart';
import GroceryForm from './GroceryForm';
🧾 GroceryList.js (sample)
jsx
CopyEdit
import React from 'react';
🧾 Cart.js (sample)
jsx
CopyEdit
import React from 'react';
Angular
@Pipe({
name: 'capitalize'
})
export class CapitalizePipe implements PipeTransform {
transform(value: string): string {
if (!value) return value;
return value.charAt(0).toUpperCase() +
value.slice(1).toLowerCase();
}
}
Explanation:
1. Pipe Decorator: @Pipe({ name: 'capitalize' }) – This marks
the class as a pipe. The name defines how we will use the pipe
in the HTML template.
2. transform Method: This method is required in a custom pipe.
It receives a value (the string to be transformed) and returns
the transformed value. In this case, it capitalizes the first letter
of the string and converts the rest to lowercase.
3. Modify the App Component
Now, let’s use both built-in and custom pipes in the
app.component.html and app.component.ts.
app.component.ts
typescript
CopyEdit
// src/app/app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'pipe-demo';
message = 'hello, angular pipes';
date = new Date();
}
Explanation:
1. Component Decorator: @Component defines the
component's selector (app-root), template URL
(app.component.html), and CSS styles.
2. Properties: The title, message, and date properties will be
used in the HTML template. date is an instance of Date, which
will demonstrate the use of built-in pipes.
app.component.html
html
CopyEdit
<!-- src/app/app.component.html -->
<div style="text-align:center">
<h1>{{ title }}</h1>
<p>{{ message | uppercase }}</p> <!-- Built-in uppercase pipe
-->
<p>{{ date | date: 'fullDate' }}</p> <!-- Built-in date pipe -->
</div>
2. Property Binding
What it is:
It sets a DOM property of an element to a component’s property.
📄 Example: Disable a button using property
html
CopyEdit
<!-- app.component.html -->
<button [disabled]="isDisabled">Can't Click Me</button>
ts
CopyEdit
// app.component.ts
export class AppComponent {
isDisabled = true;
}
✅ Explanation:
[disabled]="isDisabled": Binds the button's disabled property
to the component variable.
4. Style Binding
What it is:
You can change the CSS styles of an element dynamically.
📄 Example: Change text color
html
CopyEdit
<!-- app.component.html -->
<p [style.color]="textColor">This is styled text.</p>
ts
CopyEdit
// app.component.ts
export class AppComponent {
textColor = 'blue';
}
✅ Explanation:
[style.color]="textColor": Binds the color style to the variable
textColor.
5. Two-Way Binding
What it is:
It allows data to flow both ways: from the component to the input
and from the input back to the component.
📄 Example: Update name live
html
CopyEdit
<!-- app.component.html -->
<input [(ngModel)]="name">
<p>Your name is: {{ name }}</p>
ts
CopyEdit
// app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
})
export class AppComponent {
name = '';
}
✅ Note: You must import FormsModule in your app.module.ts for
[(ngModel)] to work:
ts
CopyEdit
import { FormsModule } from '@angular/forms';
@NgModule({
imports: [BrowserModule, FormsModule],
})
export class AppModule {}
✅ Explanation:
[(ngModel)]="name": Syncs the input field and the name
variable both ways.
These are custom components you create. Every Angular component is a directive with a template.
🔹 Example
📄 app.component.ts
ts
CopyEdit
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `<h2>Hello from App Component!</h2>`
})
export class AppComponent {}
✅ 2. Structural Directives
📄 app.component.html
html
CopyEdit
<h2 *ngIf="show">This text is conditionally shown</h2>
<button (click)="show = !show">Toggle</button>
📄 app.component.ts
ts
CopyEdit
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html'
})
export class AppComponent {
show = true;
}
🔸 Example 2 – *ngFor
html
CopyEdit
<ul>
<li *ngFor="let item of items">{{ item }}</li>
</ul>
ts
CopyEdit
items = ['Apple', 'Banana', 'Orange'];
✅ 3. Attribute Directives
📄 highlight.directive.ts
ts
CopyEdit
import { Directive, ElementRef } from '@angular/core';
@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective {
constructor(el: ElementRef) {
el.nativeElement.style.backgroundColor = 'yellow';
}
}
📄 Usage in app.component.html
html
CopyEdit
<p appHighlight>This paragraph is highlighted</p>
📄 app.module.ts
ts
CopyEdit
import { HighlightDirective } from './highlight.directive';
@NgModule({
declarations: [AppComponent, HighlightDirective],
...
})
✅ Example:
ts
CopyEdit
import { Directive, ElementRef } from '@angular/core';
@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective {
constructor(private el: ElementRef) {
el.nativeElement.style.backgroundColor = 'yellow';
}
}
📌 Explanation:
appHighlight is a custom attribute directive.
The directive uses dependency injection to inject
ElementRef, which gives direct access to the element it's
applied on.
The directive then sets the element’s background color using
this injected reference.
Unit V