Djang Course File

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 151

Node JS/ React JS/

Django
COURSE FILE
DEPARTMENT OF COMPUTER SCIENCE AND ENGINEERING

Programme UG

Branch CSE

Name of the Subject Node JS/ React JS/ Django

Year & Semester II B.Tech II - Sem

Section A,B,C

E.satishBabu

Prepared by Assistant Professor

CSE

Verified by :
Approved by:

HOD-CSE
Course File –Contents

S. No. Title
1 Syllabus Prescribed by University
2 Programme Educational Objectives (PEOs)
3 Programme Outcomes (POs)

Course Outcomes (must be measurable and use action verbs as


4
per blooms taxonomy) & Mapping with POs & PSOs

Lesson Plan/Lecture Schedule with methodology being used /


5
adopted( At least 5 Pedagogies should be used)

University question papers of present and previous two years


6
(regular & Supplementary)

Unit Wise Assignment Questions(Indicate level of Blooms


7
Taxonomy)(2 copies of Assignments)
8 Mid Question Papers with Scheme of Evaluation
9 Marks List
Class Test Question Papers with award list (2 copies of Class
10
Test books)
11 Results Analysis Information
CO attainments (along with target level & indication of
12
reached level of attainment)
13 Topics Beyond Syllabus
14 Lecture Notes/Handouts and additional material.
15 Power point Presentations
R22 B.Tech.CSE

NODE JS/ REACT JS/ DJANGO

Exercises:
1. Build a responsive web application for shopping cart with registration, login, catalog and cart
pages using CSS3 features, flex and grid.
2. Make the above web application responsive web application using Bootstrap framework.
3. Use JavaScript for doing client – side validation of the pages implemented in experiment 1 and
experiment 2.
4. Explore the features of ES6 like arrow functions, callbacks, promises, async/await. Implement
an application for reading the weather information from openweathermap.org and display the
information in the form of a graph on the web page.
5. Develop a java stand alone application that connects with the database (Oracle / mySql) and
perform the CRUD operation on the database tables.
6. Create an xml for the bookstore. Validate the same using both DTD and XSD.
7. Design a controller with servlet that provides the interaction with application developed in
experiment 1 and the database created in experiment 5.
8. Maintaining the transactional history of any user is very important. Explore the various sessions
9. Create a custom server using http module and explore the other modules of Node JS like OS,
path, event.
10. Develop an express web application that can interact with REST API to perform CRUD
operations on student data. (Use Postman)
11. For the above application create authorized end points using JWT (JSON Web Token).
12. Create a react application for the student management system having registration, login,
contact, about pages and implement routing to navigate through these pages.
13. Create a service in react that fetches the weather information from openweathermap.org and
the display the current and historical weather information using graphical representation using
chart.js
14. Create a TODO application in react with necessary components and deploy it into github.

REFERENCE BOOKS:

1. Jon Duckett, Beginning HTML, XHTML, CSS, and JavaScript, Wrox Publications, 2010
2. Bryan Basham, Kathy Sierra and Bert Bates, Head First Servlets and JSP, O’Reilly Media, 2nd
Edition, 2008.
3. Vasan Subramanian, Pro MERN Stack, Full Stack Web App Development with Mongo,
Express, React, and Node, 2nd Edition, A Press.
DEPARTMENT OF COMPUTER SCIENCE AND ENGINEERING

Programme Educational Objectives (PEOs)

PEO1- To provide the learners with fundamental knowledge of applied mathematics, applied sciences
and basic engineering subjects to analyze and solve the problems in Computer Science and
Engineering and its allied fields.

PEO2 - To provide learners with a concrete knowledge in the Core areas like Programming languages,
Computer Organization & Architecture, Operating Systems, Networking, Database Management
Systems, Information & Network Security, Data Mining, etc. and with cutting edge technologies.

PEO3 –To nurture the learners with breadth subjects knowledge and competence in the areas of ES,
VLSI, cloud computing , BigData, Android, Multimedia, IM, Management Science, ENS etc. by
understanding the value of efficient design and development of solutions with multidisciplinary
approach catering to the real-time requirements

PEO4 –To inculcate the learners with advanced subjects knowledge, professional practice,
entrepreneurial skills, teamwork, leadership, project management, personal and professional growth
with ethics and character in developing effective communication, interpersonal and multidisciplinary
skills.

PEO5 –To prepare the learners for higher education, employability, innovative CSE program specific
areas of global technological appliances, research, and service attitude by providing advanced methods
of teaching and learning with effective communication & lifelong learning skills and by executing
MOUs with renowned industries and premier institutes.
.DEPARTMENT OF COMPUTER SCIENCE AND ENGINEERING

PROGRAM OUTCOMES

PO1. Build a custom website with HTML, CSS, and Bootstrap and little JavaScript.

PO2. Demonstrate Advanced features of JavaScript and learn about JDBC

PO3. Develop Server – side implementation using Java technologies like

PO4. Develop the server – side implementation using Node JS.

PO5. Design a Single Page Application using React.

PSOs - CSE

PSO1: Graduates will demonstrate the knowledge in allied areas of Computer Science & Engineering.

PSO2: The learners will be able to gain desired knowledge for the Competitive Environment.
DEPARTMENT OF COMPUTER SCIENCE AND ENGINEERING

Course Objectives:
For Node JS/ React JS/ Django, the course will enable the students to:
 To implement the static web pages using HTML and do client side validation using
JavaScript.
 To design and work with databases using Java
 To develop an end to end application using java full stack.
 To introduce Node JS implementation for server side programming.
 To experiment with single page application development using React.

Course Outcomes:
Upon completion of this course, the student will be able to:

CO1:Analyze algorithms and estimate their best-case, worst-case and average-case behavior in terms
of time and space complexity.
CO2:Design appropriate algorithm for solving problems using Divide and Conquer, Backtracking.

CO3:Identify the suitable data structures and algorithm designmethods impact the performance of an
algorithm using dynamic programming.
CO4:Apply algorithm design principles to derive solutions for real life problems using greedy method.
.
Mapping of Course Outcomes with Program Outcomes:
Name of the Subject: Node JS/ React JS/ Django
Regulation: R-22

Subj P P P P
Ye Se Subject ect CO P P P P P P P P P P O O S S
ar m Name Cod PO O O O O O O O O O O 1 1 O O
e 1 2 3 4 5 6 7 8 9 10 1 2 1 2
CO1 2 3 2 2 1 - - - - 2 2 2 2 3

CO2
2 3 1 2 1 - - - - 2 2 2 2 3
Node JS/
React CO3
II II ---- 2 2 2 2 1 - - - - 2 2 2 2 3
JS/
Django CO4
2 3 2 2 2 - - - - 2 2 2 2 2

CO5
2 3 2 2 2 - - - - 2 2 2 2 2
DEPARTMENT OF COMPUTER SCIENCE AND ENGINEERING
LESSON PLAN

SUBJECT: Node JS/ React JS/ Django YEAR / SEMESTER: II-II


NAME OF THE FACULTY: E.satishBabu YEAR:2023-24
Method of No. of
Sl.No. Syllabus Content Sub Topics Covered
teaching Hours
Build a responsive web
application for
shopping cart with
CHALK AND
1 registration, login, 1
TALK
catalog and cart
pages using CSS3
features, flex and grid.
Make the above web
application
CHALK AND
2 responsive web TALK
1
application using
Bootstrap framework
Use JavaScript for
doing client – side
validation of the pages CHALK AND
3 1
implemented in TALK
experiment 1 and
experiment 2.
4 Explore the features of CHALK AND 1
ES6 like arrow TALK
functions, callbacks,
promises, async/await.
Implement
an application for
reading the weather
information from
openweathermap.org
and display the
information in the
form of a graph on the
web page.
Develop a java
stand alone
application that
connects with the
database
(Oracle / mySql) CHALK AND
5 and 1
TALK
perform the
CRUD operation
on the database
tables.

Create an xml for the


bookstore. Validate the CHALK AND
6 1
same using both DTD TALK
and XSD.
Design a controller with
servlet that provides the
interaction with
CHALK AND
7 application developed 1
TALK
in experiment 1 and
the database created in
experiment 5.
Maintaining the
transactional history of
CHALK AND
8 any user is very 1
TALK
important. Explore the
various sessions
Create a custom server
using http module and
SEMINAR BY
9 explore the other 1
STUDENTS
modules of Node JS
like OS, path, event.
. Develop an express
web application that
can interact with REST
CHALK AND
10 API to perform CRUD 1
TALK
operations on
student data. (Use
Postman)
For the above
application create
11 authorized end points ROLE PLAY 1
using JWT (JSON Web
Token).
12 Create a react CHALK AND 1
application for the
student management
system having
registration, login,
TALK
contact, about pages
and implement routing
to navigate through
these pages.
Create a service in react
that fetches the weather
information from
openweathermap.org
and
CHALK AND
13 the display the 1
TALK
current and historical
weather information
using graphical
representation using
chart.js
Create a TODO
application in
react with
necessary
components and CHALK AND
14 1
TALK
deploy it into
github.

FACULTY INCHARGE HOD-CSE


1. Build a responsive web application for shopping cart with registration, login, catalog and cart
pages using CSS3 features, flex and grid.

First, we create a components folder; this houses our reusable components, for example, Navbar.

We will continue by setting up our user interface (UI) for the application. You can get all UI
components from WrapPixel’s UI Kit. WrapPixel is an online template store where you could get
great Free React Dashboard and React Bootstrap Templates.

We will add the bootstrap CDN to our root index.html file inside the public directory.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta name="description" content="Web site created using create-react-app" />
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<link rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"
integrity="sha384-
JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z"
crossorigin="anonymous">
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<title>Shopping cart</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>
Then we add a Navbar.js file to the components folder. This is where we will handle our routing.

import React from "react"


import {
Link
} from "react-router-dom"
export const Navbar = () => {
return ( <
nav className = "navbar navbar-expand-lg navbar-light bg-info" >
<
div className = "container" >
<
Link to = "/"
className = "navbar-brand" > Vue Cart < /Link>
<
div className = "collapse navbar-collapse justify-content-end"
id = "navbarNav" >
<
ul className = "navbar-nav" >
<
li className = "nav-item active" >
<
Link to = "/"
className = "nav-link" > Home < /Link> < /
li > <
li className = "nav-item" >
<
Link to = "/cart"
className = "nav-link" > Cart < /Link> < /
li > <
/ul> < /
div > < /div> < /
nav >
)
}
Remember that we are using react-router-dom to route pages, so we need to add Navbar below
our switch, as seen below ‘App.js’

import React from "react"


import { Switch } from "react-router-dom"
import { Navbar } from "./components/Navbar"

import "./App.css"
function App() {
return (
<div className='App'>
<Navbar />
<Switch>
// Our pages will go here
</Switch>
</div>
)
}
export default App
Secondly, we create a page folder. This folder houses our pages(product and cart page), all our
services and views will be rendered in the pages for routing.

Let’s create a simple Product.js


import React, { useState, useEffect } from "react";
import { Link } from "react-router-dom";
export const Products = () => {
const [products, setProducts] = useState([]);
const [hasError, setError] = useState(false);
async function fetchData() {
const res = await fetch("http://localhost:4000/product");
res
.json()
.then((res) => {
console.log(res.data);
setProducts(res.data);
})
.catch((error) => {
setError(error);
});
}
async function addToCart(id, quantity) {
try {
const response = await fetch("http://localhost:4000/cart", {
method: "POST",
body: JSON.stringify({
productId: id,
quantity: quantity,
}),
headers: {
"Content-type": "application/json; charset=UTF-8",
},
});
let data = await response.json();
alert("Item Added To Cart");
console.log(data);
} catch (err) {
alert("Something Went Wrong");
console.log(err);
}
}
useEffect(() => {
fetchData();
}, []);
console.log(products);
return (
<main>
<section>
<div className="banner-innerpage">
<div className="container">
<div className="row justify-content-center">
<div className="col-md-6 align-self-center text-center">
<h1 className="title">Shop listing</h1>
<h6 className="subtitle op-8">
We are small team of creative people working together
</h6>
</div>
</div>
</div>
</div>
</section>
<section>
<div className="spacer">
<div className="container">
<div className="row mt-5">
<div className="col-lg-9">
<div className="row shop-listing">
{products.map((product, i) => (
<div className="col-lg-4">
<div className="card shop-hover border-0">
<img
src={"http://localhost:4000/" + product.image}
alt="wrapkit"
className="img-fluid"
/>
<div className="card-img-overlay align-items-center">
<button
onClick={(e) => addToCart(product._id, 1)}
className="btn btn-md btn-info"
>
Add to cart
</button>
</div>
</div>
<div className="card border-0">
<h6>
<a href="#" className="link">
{product.name}{" "}
</a>
</h6>
<h6 className="subtitle">by Wisdom</h6>
<h5 className="font-medium m-b-30">
$195 /{" "}
<del className="text-muted line-through">$225</del>
</h5>
</div>
</div>
))}
</div>
</div>
</div>
</div>
</div>
</section>
</main>
);
};
Noticed the fetchData function? We make an HTTP request to the backend to list all products and
store them in the variable products (we are using React hooks, remember).

Since we have it as an array now, we loop through it to display as seen on line 64.

We will also need to add items to the cart, which will be an async method making a request to the
backend with its parameters passed to it. This is a very important feature as well.

The addToCart is defined on line 18:

async function addToCart(id, quantity) {


try {
const response = await fetch("http://localhost:4000/cart", {
method: "POST",
body: JSON.stringify({
productId: id,
quantity: quantity,
}),
headers: {
"Content-type": "application/json; charset=UTF-8",
},
})
let data = await response.json()
console.log(data)
} catch (err) {
console.log(err)
}
}
After that, We add the event listener to the button to call the addToCart button

<button
onClick={(e) => addToCart(product._id, 1)}
className="btn btn-md btn-info"
>
Add to cart
</button>
Here, we pass the id of the product and a default quantity as 1.

Then add to our App.js once again, as a page.


import React from "react"
import { Switch, Route } from "react-router-dom"
import { Products } from "./pages/product"

import { Navbar } from "./components/Navbar"

import "./App.css"
function App() {
return (
<div className='App'>
<Navbar />
<Switch>
<Route exact path='/' component={Products} />
</Switch>
</div>
)
}
export default App

Let’s head over to the cart page and add our simple UI.

We then add a method to fetch a list of our cart items from the backend. Notice the fetchCart method
below. Doing as pleased.

If you are not familiar with react hooks, you could always look it up or better still use the component-
based.

import React, { useState, useEffect } from "react";


import { Link } from "react-router-dom";
import "./cart.css";
export const Cart = (props) => {
const [carts, setCarts] = useState([]);
const [payload, setPayloader] = useState({});
const [hasError, setError] = useState(false);
async function fetchCart() {
const res = await fetch("http://localhost:4000/cart");
res
.json()
.then((res) => {
console.log(res.data.items);
setCarts(res.data.items);
setPayloader(res.data);
})
.catch((error) => {
setError(error);
});
}
async function increaseQty(id) {
try {
const res = await fetch("http://localhost:4000/cart", {
method: "POST",
body: JSON.stringify({
productId: id,
quantity: 1,
}),
headers: {
"Content-type": "application/json; charset=UTF-8",
},
});
console.log(res);
fetchCart();
alert("Item Increamented");
} catch (err) {
console.log(err);
}
}
async function emptyCart() {
try {
const res = await fetch("http://localhost:4000/cart/empty-cart", {
method: "DELETE",
});
await res.json();
fetchCart();
props.history.push("/");
} catch (err) {
console.log(err);
}
}
useEffect(() => {
fetchCart();
}, []);
return (
<main>
<section>
<div className="banner-innerpage">
<div className="container">
<div className="row justify-content-center">
<div className="col-md-6 align-self-center text-center">
<h1 className="title">Cart Listing</h1>
<h6 className="subtitle op-8">
We are small team of creative people working together
</h6>
</div>
</div>
</div>
</div>
</section>
<section>
<div className="spacer">
<div className="container">
<div className="row mt-5">
<div className="col-lg-9">
<div className="row shop-listing">
<table className="table shop-table">
<tr>
<th className="b-0">Name</th>
<th className="b-0">Price</th>
<th className="b-0">Quantity</th>
<th className="b-0 text-right">Total Price</th>
</tr>
{carts.map((item, i) => (
<tr>
<td>{item.productId.name}</td>
<td>{item.productId.price}</td>
<td>
<button
onClick={(e) => increaseQty(item.productId._id)}
className="btn btn-primary btn-sm"
>
+
</button>
{item.quantity}
<button className="btn btn-primary btn-sm">-</button>
</td>
<td className="text-right">
<h5 className="font-medium m-b-30">{item.total}</h5>
</td>
</tr>
))}
<tr>
<td colspan="3" align="right">
Subtotal :{payload.subTotal}
</td>
<td colspan="4" align="right">
<button
className="btn btn-danger"
onClick={(e) => emptyCart()}
>
Empty cart
</button>
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
</div>
</section>
</main>
);
};
We can then loop through the array(cart) and modify it.

Notice the increamentQty(id) the method which takes the product id as a parameter and then set
the quantity to one as default as we are updating the quantity by one.

async function increaseQty(id) {


try {
const res = await fetch("http://localhost:4000/cart", {
method: "POST",
body: JSON.stringify({
productId: id,
quantity: 1,
}),
headers: {
"Content-type": "application/json; charset=UTF-8",
},
});
console.log(res);
fetchCart();
alert("Item increamented");
} catch (err) {
console.log(err);
}
}
After doing that we added a click event to our button to trigger the method:

<button
onClick={(e) => increaseQty(item.productId._id)}
className="btn btn-primary btn-sm"
>
+
</button>
Clicking on the button will increment the quantity of the item.

We then define an emptyCart the method as well to delete all items currently in the cart. See below;

async function emptyCart() {


try {
const res = await fetch("http://localhost:4000/cart/empty-cart", {
method: "DELETE",
});
await res.json();
fetchCart();
props.history.push("/");
} catch (err) {
console.log(err);
}
}

2. Make the above web application responsive web application using Bootstrap framework.

<!
DOCTYPE
html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-
scale=1, shrink-to-fit=no">
<meta http-equiv="x-ua-compatible" content="ie=edge">

<!-- Bootstrap CSS -->


<link rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstr
ap.min.css"
integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlf
IDPvg6uqKI2xXr2" crossorigin="anonymous">
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css
/font-awesome.min.css">
<style type="text/css">
.jumbotron{
padding-top: 80px;
padding-bottom: 50px;
}
#jumbo{
height: 100px;
background-color: #e0e0eb;
margin-top: 30px;
padding-top: 30px;
}

footer{
margin-top: 60px;
background-color: pink;
padding-top: 40px;
}
.fa {
padding: 6px;
width: 35px;
text-align: center;
text-decoration: none;
margin: 5px 2px;
}
.fa-google-plus{
color: white;
background-color: #dd4b39;
}
.fa-facebook{
color: white;
background-color: #3B5998;
}
.fa-linkedin{
color: white;
background-color: #007bb5;
}
.fa-twitter{
color: white;
background-color: #55ACEE;
}
.fa-youtube{
color: white;
background-color: #bb0000;
}
</style>
</head>
<body>
<nav class="navbar navbar-dark navbar-expand-sm bg-primary
fixed-top">
<div class="container">
<button class="navbar-toggler" type="button" data-
toggle="collapse" data-target="#Navbar">
<span class="navbar-toggler-icon"></span>
</button>
<a class="navbar-brand mr-auto"
href="./index.html">InfoLabzz</a>
<div class="collapse navbar-collapse" id="Navbar">
<ul class="navbar-nav ml-auto">
<li class="nav-item active"><a class="nav-link"
href="./index.html"><span class="fa fa-home fa-lg"></span>
Home</a></li>
<li class="nav-item"><a class="nav-link"
href="./about.html"><span class="fa fa-info fa-lg"></span>
About</a></li>
<li class="nav-item"><a class="nav-link"
href="./contact.html"><span class="fa fa-address-card fa-
lg"></span> Contact</a></li>
</ul>
</div>

</div>
</nav>
<header class="jumbotron">
<div class="container">
<div class="row">
<div class="col-12 col-sm-12 col-md-12 col-lg-12
col-xl-12">
<h1 class="text-center">Welcome to
InfoLabzz</h1>
</div>
</div>
</div>
</header>

<div class="container">
<div class="row">
<div class="col-12 col-sm-5 col-md-5 col-lg-5 col-xl-5
text-center" id="jumbo">
<button type="button" class="btn btn-success"><a
href="./addemp.html" style="text-decoration: none; color:
#FFFFFF">Add new employee</a></button>
</div>
<div class="col-12 col-sm-5 col-md-5 col-lg-5 col-xl-5
offset-sm-2 offset-md-2 offset-lg-2 offset-xl-2 text-center"
id="jumbo">
<button type="button" class="btn btn-warning"><a
href="./modifyemp.html" style="text-decoration: none; color:
#FFFFFF">Modify an employee</a></button>
</div>
</div>
<div class="row">
<div class="col-12 col-sm-5 col-md-5 col-lg-5 col-xl-5
text-center" id="jumbo">
<button type="button" class="btn btn-info"><a
href="./viewemp.html" style="text-decoration: none; color:
#FFFFFF">View an employee</a></button>
</div>
<div class="col-12 col-sm-5 col-md-5 col-lg-5 col-xl-5
offset-sm-2 offset-md-2 offset-lg-2 offset-xl-2 text-center"
id="jumbo">
<button type="button" class="btn btn-danger"><a
href="./delemp.html" style="text-decoration: none; color:
#FFFFFF">Delete an employee</a></button>
</div>
</div>
</div>
<footer class="footer">
<div class="container">
<div class="row">
<div class="col-4 col-sm-3 col-md-3 col-lg-3 col-
xl-3">
<h5>Links</h5>
<ul class="list-unstyled">
<li><a href="./index.html">Home</a></li>
<li><a href="./about.html">About</a></li>
<li><a
href="./contact.html">Contact</a></li>
</ul>
</div>
<div class="col-8 col-sm-6 col-md-6 col-lg-6 col-
xl-6 text-center">
<h5>Our Address</h5>
<address>
121, Clear Water Bay Road<br>
<i class="fa fa-phone fa-lg"></i> +91-
908567896<br>
<i class="fa fa-fax fa-lg"></i> +91-
908567896<br>
<i class="fa fa-envelope fa-lg"></i> <a
href="mailto:[email protected]">[email protected]</a>
</address>
</div>
<div class="col-12 col-sm-3 col-md-3 col-lg-3 col-
xl-3">
<h5 class="text-center">Connect with us</h5>
<div class="text-center">
<a href="http://google.com/+"><i class="fa
fa-google-plus fa-lg"></i></a>
<a
href="http://www.facebook.com/profile.php?id="><i class="fa fa-
facebook fa-lg"></i></a>
<a href="http://www.linkedin.com/in/"><i
class="fa fa-linkedin fa-lg"></i></a>
<a href="http://twitter.com/"><i class="fa
fa-twitter fa-lg"></i></a>
<a href="http://youtube.com/"><i class="fa
fa-youtube fa-lg"></i></a>
</div>
</div>
</div>
<div class="row justify-content-center">
<div class="col-auto">
<p>© Copyright 2020 <a
href="./about.html">InfoLabzz Pvt. Ltd.</a></p>
</div>
</div>
</div>
</footer>
<!-- jQuery first, then Popper.js, then Bootstrap JS. -->
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"
integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+Ibb
VYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script
src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.
min.js"
integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZ
p6G7niu735Sk7lN" crossorigin="anonymous"></script>
<script
src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap
.min.js" integrity="sha384-
w1Q4orYjBQndcko6MimVbzY0tgp4pWB4lZ7lr30WKz0vr/aWKhXdBNmNb5D92v7s"
crossorigin="anonymous"></script>
</body>
</html>

3.Use JavaScript for doing client – side validation of the pages implemented in experiment 1 and
experiment 2.

form>
<p>
<fieldset>
<legend>Do you have a driver's license?<span aria-label="required">*</span></legend>
<!-- While only one radio button in a same-named group can be selected at a time,
and therefore only one radio button in a same-named group having the "required"
attribute suffices in making a selection a requirement -->
<input type="radio" required name="driver" id="r1" value="yes"><label for="r1">Yes</label>
<input type="radio" required name="driver" id="r2" value="no"><label for="r2">No</label>
</fieldset>
</p>
<p>
<label for="n1">How old are you?</label>
<!-- The pattern attribute can act as a fallback for browsers which
don't implement the number input type but support the pattern attribute.
Please note that browsers that support the pattern attribute will make it
fail silently when used with a number field.
Its usage here acts only as a fallback -->
<input type="number" min="12" max="120" step="1" id="n1" name="age"
pattern="\d+">
</p>
<p>
<label for="t1">What's your favorite fruit?<span aria-label="required">*</span></label>
<input type="text" id="t1" name="fruit" list="l1" required
pattern="[Bb]anana|[Cc]herry|[Aa]pple|[Ss]trawberry|[Ll]emon|[Oo]range">
<datalist id="l1">
<option>Banana</option>
<option>Cherry</option>
<option>Apple</option>
<option>Strawberry</option>
<option>Lemon</option>
<option>Orange</option>
</datalist>
</p>
<p>
<label for="t2">What's your email address?</label>
<input type="email" id="t2" name="email">
</p>
<p>
<label for="t3">Leave a short message</label>
<textarea id="t3" name="msg" maxlength="140" rows="5"></textarea>
</p>
<p>
<button>Submit</button>
</p>
</form>
Copy to Clipboard

And now some CSS to style the HTML:

form {
font: 1em sans-serif;
max-width: 320px;
}

p > label {
display: block;
}

input[type="text"],
input[type="email"],
input[type="number"],
textarea,
fieldset {
width: 100%;
border: 1px solid #333;
box-sizing: border-box;
}

input:invalid {
box-shadow: 0 0 5px 1px red;
}

input:focus:invalid {
box-shadow: none;
}

4. Explore the features of ES6 like arrow functions, callbacks, promises, async/await. Implement
an application for reading the weather information from openweathermap.org and display the
information in the form of a graph on the web page.
5. Develop a java stand alone application that connects with the database (Oracle / mySql)
and perform the CRUD operation on the database tables.

CRUD stands for Create, Read/Retrieve, Update and Delete and these are the four basic
operations that we perform on persistence storage. CRUD is data-oriented and the
standardized use of HTTP methods. HTTP has a few methods which work as CRUD
operations and do note they are very vital from a developmental point perspective in
programming that also does helps us relate better web development and also aids us while
dealing with databases.
So, standard CRUD Operations is as follows:
 POST: Creates a new resource
 GET: Reads/Retrieve a resource
 PUT: Updates an existing resource
 DELETE: Deletes a resource

As the name suggests


 CREATE Operation: Performs the INSERT statement to create a new record.
 READ Operation: Reads table records based on the input parameter.
 UPDATE Operation: Executes an update statement on the table. It is based on the
input parameter.
 DELETE Operation: Deletes a specified row in the table. It is also based on the input
parameter.
So in this article, we are going to perform some basic CRUD Operations by creating a
Spring Boot Application and using the MySQL Database. So here is a brief explanation of
What’s Spring Boot and What’s MySQL Database.
Spring Boot
Spring Boot is built on the top of the spring and contains all the features of spring. And is
becoming a favorite of developers these days because it’s a rapid production-ready
environment that enables the developers to directly focus on the logic instead of struggling
with the configuration and setup. Spring Boot is a microservice-based framework and
making a production-ready application in it takes very little time.

MySQL Database
MySQL is an RDBMS (Relational Database Management System) based on the SQL
(Structured Query Language), which is the popular language for accessing and managing
the records in the database. MySQL is open-source and free software under the GNU
license. It is supported by Oracle Company. The data in a MySQL database are stored in
tables. A table is a collection of related data, and it consists of columns and rows. Some of
the features of MySQL are listed below:
1. It is a database system used on the web
2. It runs on a server
3. It is ideal for both small and large applications
4. It is very fast, reliable, and easy to use
5. It uses standard SQL
6. It is free to download and use
So to connect and perform CRUD operation with the MySQL DB with Spring Boot
application we have to just configure it inside the application.properties file as follows:

# Configuration for MySQL Database


spring.jpa.hibernate.ddl-auto=update

spring.datasource.url = jdbc:mysql://localhost:3306/schooldb
(Datasource URL of your DB and "schooldb", here is your schema name)

spring.datasource.username=amiya559 (Your MySQL Workbench user name)


spring.datasource.password=password.123 (Your MySQL Workbench password)
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.show-sql:true
Illustration:
public interface DepartmentRepository extends JpaRepository<Department,
Long> {}

Example: We will be having a Spring Boot application that manages a Department


entity with JpaRepository. The data is saved in the MySQL database. We use a
RESTful controller.
Step 1: Create a Spring Boot project with say it be IntelliJ
Step 2: Add the following dependency as listed below as follows:
 Spring Web
 MySQL Database
 Lombok
 Spring Data JPA

 XML
<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<parent>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-parent</artifactId>

<version>2.5.5</version>

<relativePath/> <!-- lookup parent from repository -->

</parent>

<groupId>com.amiya</groupId>

<artifactId>Spring-Boot-Demo-Project</artifactId>

<version>1.0.0-SNAPSHOT</version>

<name>Spring-Boot-Demo-Project</name>

<description>Demo project for Spring Boot</description>

<properties>

<java.version>11</java.version>

</properties>
<dependencies>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-web</artifactId>

</dependency>

<!-- Dependency for MySQL Database -->

<dependency>

<groupId>mysql</groupId>

<artifactId>mysql-connector-java</artifactId>

<scope>runtime</scope>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-devtools</artifactId>

<scope>runtime</scope>

<optional>true</optional>
</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-data-jpa</artifactId>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-test</artifactId>

<scope>test</scope>

</dependency>

<dependency>

<groupId>org.projectlombok</groupId>

<artifactId>lombok</artifactId>

<optional>true</optional>

</dependency>
</dependencies>

<build>

<plugins>

<plugin>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-maven-plugin</artifactId>

<configuration>

<excludes>

<exclude>

<groupId>org.projectlombok</groupId>

<artifactId>lombok</artifactId>

</exclude>

</excludes>

</configuration>

</plugin>

</plugins>

</build>
</project>

Step 4: Inside the entity package


It is done via creating a simple POJO class inside the Department.java file.
 Java

// Java Program to Illustrate Department File

// Importing package module to code fragment

package com.amiya.springbootdemoproject.entity;

// Importing required classes

import lombok.AllArgsConstructor;

import lombok.Builder;

import lombok.Data;

import lombok.NoArgsConstructor;

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;

import javax.persistence.Id;

// Annotations

@Entity

@Data

@NoArgsConstructor

@AllArgsConstructor

@Builder

// Class

public class Department {

@Id

@GeneratedValue(strategy = GenerationType.AUTO)

private Long departmentId;

private String departmentName;

private String departmentAddress;

private String departmentCode;

}
Step 5: Inside the repository package
Create a simple interface and name the interface as DepartmentRepository. This
interface is going to extend the JpaRepository as we have discussed above.

Example
 Java

// Java Program to Illustrate DepartmentRepository File

// Importing package module to this code

package com.amiya.springbootdemoproject.repository;

// Importing required classes

import com.amiya.springbootdemoproject.entity.Department;

import org.springframework.data.jpa.repository.JpaRepository;

import org.springframework.stereotype.Repository;

// Annotation

@Repository

// Interface
public interface DepartmentRepository

extends JpaRepository<Department, Long> {

Step 6: Inside the service package


Example 1-A Inside the package create one interface named
as DepartmentService and one class named as DepartmentServiceImpl.
 Java

// Java Program to Illustrate DepartmentService File

// Importing package to this code fragment

package com.amiya.springbootdemoproject.service;

import com.amiya.springbootdemoproject.entity.Department;

// Importing required classes

import java.util.List;

// Interface

public interface DepartmentService {


// Save operation

Department saveDepartment(Department department);

// Read operation

List<Department> fetchDepartmentList();

// Update operation

Department updateDepartment(Department department,

Long departmentId);

// Delete operation

void deleteDepartmentById(Long departmentId);

Example 1-B
 Java

// Java Program to Illustrate DepartmentServiceImpl File


// Importing package module to this code

package com.amiya.springbootdemoproject.service;

import com.amiya.springbootdemoproject.entity.Department;

import
com.amiya.springbootdemoproject.repository.DepartmentRepository;

// Importing required classes

import java.util.List;

import java.util.Objects;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

// Annotation

@Service

// Class

public class DepartmentServiceImpl

implements DepartmentService {

@Autowired
private DepartmentRepository departmentRepository;

// Save operation

@Override

public Department saveDepartment(Department department)

return departmentRepository.save(department);

// Read operation

@Override public List<Department> fetchDepartmentList()

return (List<Department>)

departmentRepository.findAll();

// Update operation

@Override

public Department
updateDepartment(Department department,

Long departmentId)

Department depDB

= departmentRepository.findById(departmentId)

.get();

if (Objects.nonNull(department.getDepartmentName())

&& !"".equalsIgnoreCase(

department.getDepartmentName())) {

depDB.setDepartmentName(

department.getDepartmentName());

if (Objects.nonNull(

department.getDepartmentAddress())

&& !"".equalsIgnoreCase(

department.getDepartmentAddress())) {

depDB.setDepartmentAddress(
department.getDepartmentAddress());

if (Objects.nonNull(department.getDepartmentCode())

&& !"".equalsIgnoreCase(

department.getDepartmentCode())) {

depDB.setDepartmentCode(

department.getDepartmentCode());

return departmentRepository.save(depDB);

// Delete operation

@Override

public void deleteDepartmentById(Long departmentId)

departmentRepository.deleteById(departmentId);

}
}

Step 7: Inside the controller package


Inside the package create one class named as DepartmentController.
 Java

// Java Program to Illustrate DepartmentController File

// Importing package module to this code

package com.amiya.springbootdemoproject.controller;

import com.amiya.springbootdemoproject.entity.Department;

import com.amiya.springbootdemoproject.service.DepartmentService;

import java.util.List;

import javax.validation.Valid;

// Importing required classes

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.*;

// Annotation
@RestController

// Class

public class DepartmentController {

// Annotation

@Autowired private DepartmentService departmentService;

// Save operation

@PostMapping("/departments")

public Department saveDepartment(

@Valid @RequestBody Department department)

return departmentService.saveDepartment(department);

// Read operation

@GetMapping("/departments")

public List<Department> fetchDepartmentList()


{

return departmentService.fetchDepartmentList();

// Update operation

@PutMapping("/departments/{id}")

public Department

updateDepartment(@RequestBody Department department,

@PathVariable("id") Long departmentId)

return departmentService.updateDepartment(

department, departmentId);

// Delete operation

@DeleteMapping("/departments/{id}")

public String deleteDepartmentById(@PathVariable("id")

Long departmentId)

{
departmentService.deleteDepartmentById(

departmentId);

return "Deleted Successfully";

7. Create an xml for the bookstore. Validate the same using both DTD and XSD.
Create an xml for the bookstore. Validate the same using both DTD and XSD.

XML DTD

An XML document with correct syntax is called "Well Formed".

An XML document validated against a DTD is both "Well Formed" and "Valid".

What is a DTD?

DTD stands for Document Type Definition.

A DTD defines the structure and the legal elements and attributes of an XML
document.

Valid XML Documents

A "Valid" XML document is "Well Formed", as well as it conforms to the rules of a


DTD:

<?xml version="1.0" encoding="UTF-8"?>


<!DOCTYPE note SYSTEM "Note.dtd">
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>

The DOCTYPE declaration above contains a reference to a DTD file. The content of
the DTD file is shown and explained below.

XML DTD

The purpose of a DTD is to define the structure and the legal elements and attributes
of an XML document:

Note.dtd:
<!DOCTYPE note
[
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
]>

The DTD above is interpreted like this:

 !DOCTYPE note - Defines that the root element of the document is note
 !ELEMENT note - Defines that the note element must contain the elements:
"to, from, heading, body"
 !ELEMENT to - Defines the to element to be of type "#PCDATA"
 !ELEMENT from - Defines the from element to be of type "#PCDATA"
 !ELEMENT heading - Defines the heading element to be of type "#PCDATA"
 !ELEMENT body - Defines the body element to be of type "#PCDATA"

An XSD Example
This chapter will demonstrate how to write an XML Schema. You will also learn
that a schema can be written in different ways.

An XML Document

Let's have a look at this XML document called "shiporder.xml":

<?xml version="1.0" encoding="UTF-8"?>

<shiporder orderid="889923"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="shiporder.xsd">
<orderperson>John Smith</orderperson>
<shipto>
<name>Ola Nordmann</name>
<address>Langgt 23</address>
<city>4000 Stavanger</city>
<country>Norway</country>
</shipto>
<item>
<title>Empire Burlesque</title>
<note>Special Edition</note>
<quantity>1</quantity>
<price>10.90</price>
</item>
<item>
<title>Hide your heart</title>
<quantity>1</quantity>
<price>9.90</price>
</item>
</shiporder>

The XML document above consists of a root element, "shiporder", that contains a
required attribute called "orderid". The "shiporder" element contains three different
child elements: "orderperson", "shipto" and "item". The "item" element appears
twice, and it contains a "title", an optional "note" element, a "quantity", and a "price"
element.

The line above: xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" tells the


XML parser that this document should be validated against a schema. The line:
xsi:noNamespaceSchemaLocation="shiporder.xsd" specifies WHERE the schema
resides (here it is in the same folder as "shiporder.xml").

Create an XML Schema


Now we want to create a schema for the XML document above.

We start by opening a new file that we will call "shiporder.xsd". To create the
schema we could simply follow the structure in the XML document and define each
element as we find it. We will start with the standard XML declaration followed by the
xs:schema element that defines a schema:

<?xml version="1.0" encoding="UTF-8" ?>


<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
...
</xs:schema>

In the schema above we use the standard namespace (xs), and the URI associated
with this namespace is the Schema language definition, which has the standard
value of http://www.w3.org/2001/XMLSchema.

Next, we have to define the "shiporder" element. This element has an attribute and
it contains other elements, therefore we consider it as a complex type. The child
elements of the "shiporder" element is surrounded by a xs:sequence element that
defines an ordered sequence of sub elements:

<xs:element name="shiporder">
<xs:complexType>
<xs:sequence>
...
</xs:sequence>
</xs:complexType>
</xs:element>

Then we have to define the "orderperson" element as a simple type (because it does
not contain any attributes or other elements). The type (xs:string) is prefixed with
the namespace prefix associated with XML Schema that indicates a predefined
schema data type:

<xs:element name="orderperson" type="xs:string"/>

Next, we have to define two elements that are of the complex type: "shipto" and
"item". We start by defining the "shipto" element:

<xs:element name="shipto">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="address" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="country" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>

With schemas we can define the number of possible occurrences for an element with
the maxOccurs and minOccurs attributes. maxOccurs specifies the maximum number
of occurrences for an element and minOccurs specifies the minimum number of
occurrences for an element. The default value for both maxOccurs and minOccurs is
1!

Now we can define the "item" element. This element can appear multiple times
inside a "shiporder" element. This is specified by setting the maxOccurs attribute of
the "item" element to "unbounded" which means that there can be as many
occurrences of the "item" element as the author wishes. Notice that the "note"
element is optional. We have specified this by setting the minOccurs attribute to
zero:

<xs:element name="item" maxOccurs="unbounded">


<xs:complexType>
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element name="note" type="xs:string" minOccurs="0"/>
<xs:element name="quantity" type="xs:positiveInteger"/>
<xs:element name="price" type="xs:decimal"/>
</xs:sequence>
</xs:complexType>
</xs:element>

We can now declare the attribute of the "shiporder" element. Since this is a required
attribute we specify use="required".

Note: The attribute declarations must always come last:

<xs:attribute name="orderid" type="xs:string" use="required"/>

Here is the complete listing of the schema file called "shiporder.xsd":

<?xml version="1.0" encoding="UTF-8" ?>


<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:element name="shiporder">
<xs:complexType>
<xs:sequence>
<xs:element name="orderperson" type="xs:string"/>
<xs:element name="shipto">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="address" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="country" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="item" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element name="note" type="xs:string" minOccurs="0"/>
<xs:element name="quantity" type="xs:positiveInteger"/>
<xs:element name="price" type="xs:decimal"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="orderid" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>

</xs:schema>

Divide the Schema

The previous design method is very simple, but can be difficult to read and maintain
when documents are complex.

The next design method is based on defining all elements and attributes first, and
then referring to them using the ref attribute.

Here is the new design of the schema file ("shiporder.xsd"):

<?xml version="1.0" encoding="UTF-8" ?>


<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<!-- definition of simple elements -->


<xs:element name="orderperson" type="xs:string"/>
<xs:element name="name" type="xs:string"/>
<xs:element name="address" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="country" type="xs:string"/>
<xs:element name="title" type="xs:string"/>
<xs:element name="note" type="xs:string"/>
<xs:element name="quantity" type="xs:positiveInteger"/>
<xs:element name="price" type="xs:decimal"/>

<!-- definition of attributes -->


<xs:attribute name="orderid" type="xs:string"/>

<!-- definition of complex elements -->


<xs:element name="shipto">
<xs:complexType>
<xs:sequence>
<xs:element ref="name"/>
<xs:element ref="address"/>
<xs:element ref="city"/>
<xs:element ref="country"/>
</xs:sequence>
</xs:complexType>
</xs:element>

<xs:element name="item">
<xs:complexType>
<xs:sequence>
<xs:element ref="title"/>
<xs:element ref="note" minOccurs="0"/>
<xs:element ref="quantity"/>
<xs:element ref="price"/>
</xs:sequence>
</xs:complexType>
</xs:element>

<xs:element name="shiporder">
<xs:complexType>
<xs:sequence>
<xs:element ref="orderperson"/>
<xs:element ref="shipto"/>
<xs:element ref="item" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute ref="orderid" use="required"/>
</xs:complexType>
</xs:element>

</xs:schema>

Using Named Types


The third design method defines classes or types, that enables us to reuse element
definitions. This is done by naming the simpleTypes and complexTypes elements,
and then point to them through the type attribute of the element.

Here is the third design of the schema file ("shiporder.xsd"):

<?xml version="1.0" encoding="UTF-8" ?>


<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:simpleType name="stringtype">
<xs:restriction base="xs:string"/>
</xs:simpleType>

<xs:simpleType name="inttype">
<xs:restriction base="xs:positiveInteger"/>
</xs:simpleType>

<xs:simpleType name="dectype">
<xs:restriction base="xs:decimal"/>
</xs:simpleType>

<xs:simpleType name="orderidtype">
<xs:restriction base="xs:string">
<xs:pattern value="[0-9]{6}"/>
</xs:restriction>
</xs:simpleType>

<xs:complexType name="shiptotype">
<xs:sequence>
<xs:element name="name" type="stringtype"/>
<xs:element name="address" type="stringtype"/>
<xs:element name="city" type="stringtype"/>
<xs:element name="country" type="stringtype"/>
</xs:sequence>
</xs:complexType>

<xs:complexType name="itemtype">
<xs:sequence>
<xs:element name="title" type="stringtype"/>
<xs:element name="note" type="stringtype" minOccurs="0"/>
<xs:element name="quantity" type="inttype"/>
<xs:element name="price" type="dectype"/>
</xs:sequence>
</xs:complexType>

<xs:complexType name="shipordertype">
<xs:sequence>
<xs:element name="orderperson" type="stringtype"/>
<xs:element name="shipto" type="shiptotype"/>
<xs:element name="item" maxOccurs="unbounded" type="itemtype"/>
</xs:sequence>
<xs:attribute name="orderid" type="orderidtype" use="required"/>
</xs:complexType>

<xs:element name="shiporder" type="shipordertype"/>

</xs:schema>

The restriction element indicates that the datatype is derived from a W3C XML
Schema namespace datatype. So, the following fragment means that the value of
the element or attribute must be a string value:

<xs:restriction base="xs:string">

The restriction element is more often used to apply restrictions to elements. Look at
the following lines from the schema above:

<xs:simpleType name="orderidtype">
<xs:restriction base="xs:string">
<xs:pattern value="[0-9]{6}"/>
</xs:restriction>
</xs:simpleType>

8. Design a controller with servlet that provides the interaction with application developed
in experiment 1 and the database created in experiment.

Building a React.js Application using Django REST Framework

We are going to create an application that consumes React for the user interface and Django for the
API of our application using Django REST framework (DRF).

Prerequisites

Basic knowledge of React, Python(Django) is required but I’ll try and boil things down as much as possible.

You can check out these articles to get started with React and Python:

 Introduction to React

 Django Tutorials

Before getting your hands dirty, you may need to:

1. Install Python 3
2. Install Node.js

Step 1: Backend using Django

From a terminal create a new project directory called django-react-todoApp

mkdir django-react-todoApp

cd django-react-todoApp

We must have a virtual environment activated to be able to install Django.

Let’s create a virtual environment and activate it:

pip install pipenv

pipenv shell

Install Django and create a project named backend:

pipenv install django

django-admin startproject backend

Now that we have created our project, let’s go ahead and create an application called todo and migrate the
models into the database.

If everything works you should see the “Congratulations” page from Django.

Navigate to backend/settings.py and add todo to the list of INSTALLED_APPS

INSTALLED_APPS = [

'django.contrib.admin',

'django.contrib.auth',

'django.contrib.contenttypes',

'django.contrib.sessions',

'django.contrib.messages',

'django.contrib.staticfiles',

'todo',

We’ll go ahead and set up our model for Todo item fields.
Modify todo/models.py as follows:

from django.db import models

class Todo(models.Model):

title = models.CharField(max_length=100)

description = models.TextField()

completed = models.BooleanField(default=False)

def _str_(self):

return self.title

The model contains:

 Title: What the task is.

 Description: Give more explanation about a particular task.

 Completed: If the task is complete the status is True otherwise it remains False.

Django uses _str_() to display a default attribute to be displayed, in our case we return title to be shown from
our model.

Let us run migrations to add our model to the database schema.

python manage.py makemigrations

python manage.py migrate

Django comes with a built-in admin interface. The interface allows administrators and authorized users to
perform actions directly to the objects defined in the models.

We can add models to our Admin page using the admin.site.register() functions. In the todo app’s admin.py,
let’s add the model to our admin page.

from django.contrib import admin

from .models import Todo

class TodoAdmin(admin.ModelAdmin):
list = ('title', 'description', 'completed')

admin.site.register(Todo, TodoAdmin)

Let’s create a superuser for the admin page to login.

python manage.py createsuperuser

This will prompt you to enter the username, email, password, password(again). We can open the admin page
using the following link http://localhost:8000/admin.

python manage.py runserver

We can now add and delete items from the admin page. Great!

Step 2: Putting in the APIs

You can learn more about APIs in this amazing article.

Install the djangorestframework and django-cors-headers:

pipenv install djangorestframework django-cors-headers

Add rest_framework and corsheaders to the INSTALLED_APPS in backend/settings.py file and modifiy
the MIDDLEWARE:

INSTALLED_APPS = [

'django.contrib.admin',

'django.contrib.auth',

'django.contrib.contenttypes',

'django.contrib.sessions',

'django.contrib.messages',

'django.contrib.staticfiles',

'todo',
'corsheaders',

'rest_framework',

MIDDLEWARE = [

'corsheaders.middleware.CorsMiddleware',

'django.middleware.security.SecurityMiddleware',

'django.contrib.sessions.middleware.SessionMiddleware',

'django.middleware.common.CommonMiddleware',

'django.middleware.csrf.CsrfViewMiddleware',

'django.contrib.auth.middleware.AuthenticationMiddleware',

'django.contrib.messages.middleware.MessageMiddleware',

'django.middleware.clickjacking.XFrameOptionsMiddleware',

Add this code snippet in backend/settings.py file:

CORS_ORIGIN_WHITELIST = [

'http://localhost:3000',

Django-cors-headers is an HTTP-header-based that allows a server to indicate any other origins to your Django
application. Cross-origin Resource Sharing (CORS). Within the CORS_ORIGIN_WHITELIST , localhost:3000 will
serve as our port.

Now, let’s create a serializer file.

A serializer is a component that converts Django models to JSON objects and vice-versa.

touch todo/serializers.py

Let’s add this to the serializers.py file:

from rest_framework import serializers


from .models import Todo

class TodoSerializer(serializers.ModelSerializer):

class Meta:

model = Todo

fields = ('id' ,'title', 'description', 'completed')

From the rest_framework package, we import the serializers. We create a class, TodoSerializer that extends
from the ModelSerializer class. We then go ahead and specify the model and fields we want to be returned.

Let’s also update the todo/views.py:

from django.shortcuts import render

from .serializers import TodoSerializer

from rest_framework import viewsets

from .models import Todo

class TodoView(viewsets.ModelViewSet):

serializer_class = TodoSerializer

queryset = Todo.objects.all()

Before creating webpages in Django we must define our URLs. A URL is an address to which a webpage is
served. Defining URLs describes what requests are returned from the views when the templates are rendered
in the browser.

In the backend/urls.py we define the URL routes for the API:

from django.contrib import admin

from django.urls import path,include

from rest_framework import routers

from todo import views

router = routers.DefaultRouter()
router.register(r'todos', views.TodoView, 'todo')

urlpatterns = [

path('admin/', admin.site.urls),

path('api/', include(router.urls))

The next module is the router.urls that provides routing for our API.

The router enables us to create the subsequent operations:

Performing CRUD operations to our items is enabled by the router.

 /todos/ - This route return each item from our API.

 todos/id - Returns a specific item and it’s id.

python manage.py runserver

We have set our backend to let us move forward to the frontend.

Step 3: Frontend using React

To install React we use the following command:

-g stands for global as we are first installing create-react-app globally:

npm install -g create-react-app

While in the parent directory - django-react-todoApp- create a React application, frontend:

create-react-app frontend

To start the server:

cd frontend

npm start

You should be able to see the default React app by now.


Next, let’s install bootstrap and reactstrap to style the user interface. You can learn more on bootstrap and
reactstrap from here.

npm install [email protected] [email protected] --legacy-peer-deps

When we open our index.js file it should resemble the code below:

import React from 'react';

import ReactDOM from 'react-dom';

import App from './App';

import reportWebVitals from './reportWebVitals';

ReactDOM.render(

<App />,

document.getElementById('root')

);

//React generated comments ignored

reportWebVitals();

ReactDOM.render() renders a React element into the DOM in the given container element. It takes two
arguments. The first is the JSX being rendered, and the second displays the container element on the HTML
page.

Substitute the below code in src/App.js:

import React, { Component } from "react"

const todoItems = [

id: 1,

title: "Nature walk in the park",

description: "Visit the park with my friends",


completed: true

},

id: 2,

title: "Visit",

description: "Got to my aunt's place",

completed: true

},

id: 3,

title: "Write",

description: "Do an article about anthropology",

completed: true

},

];

class App extends Component {

constructor(props) {

super(props);

this.state = {todoItems};

};

render() {
return (

<main className="content">

<div className="row">

<div className="col-md-6 col-sm-10 mx-auto p-0">

<div className="card p-3">

<ul className="list-group list-group-flush">

{this.state.todoItems.map(item => (

<div>

<h1>{item.title}</h1>

<span>{item.description}</span>

</div>

))}

</ul>

</div>

</div>

</div>

</main>

export default App;

We start by rendering a list of items. The list will be artificial data but later we’ll fetch the data from the API we
created in the previous steps.

We define a list of items. Each item has an id, title, description, and status of whether the task is completed or
not, completed.
We introduce the class constructor where we set the initial state. In our case, the internal state is the dummy
list of items, todoItems.

We use the built-in JavaScript map functionality in our JavaScript XML (JSX).

The map() method creates a new array populated with the results of calling a provided function on every
element in the calling array. We use curly braces to evaluate JavaScript expressions.

The render() method when called displays the JSX. The classname attribute in the render() method enables us
to use the CSS properties.

We use arrow functions because they shorten our functions declaration.

Your User Interface should resemble the one below:

It is time to consume the API we created earlier.

cd backend

python manage.py runserver

We’ll need to modify the frontend/package.json by adding proxy. A proxy is used in the development
environment to facilitate communication between the server and the UI since the backend and the UI will be
running on different ports.

The proxy enables us to use Django’s localhost which handles our API requests.

Let’s go ahead and add it.

[...]

"name": "frontend",

"version": "0.1.0",

"private": true,

"proxy": "http://localhost:8000",

"dependencies": {

"@testing-library/jest-dom": "^5.11.9",

"@testing-library/react": "^11.2.3",

"@testing-library/user-event": "^12.6.0",
"react": "^17.0.1",

"react-dom": "^17.0.1",

"react-scripts": "4.0.1",

"web-vitals": "^0.2.4"

"reactstrap": "^8.8.1",

},

[...]

To consume our API instead of the artificial data, update the frontend/src/App.js with the snippet below:

import React, { Component } from "react"

class App extends Component {

constructor(props) {

super(props);

this.state = {

viewCompleted: false,

activeItem: {

title: "",

description: "",

completed: false

},

todoList: []

};

async componentDidMount() {
try {

const res = await fetch('http://localhost:8000/api/todos/');

const todoList = await res.json();

this.setState({

todoList

});

} catch (e) {

console.log(e);

renderItems = () => {

const { viewCompleted } = this.state;

const newItems = this.state.todoList.filter(

item => item.completed === viewCompleted

);

return newItems.map(item => (

<li

key={item.id}

className="list-group-item d-flex justify-content-between align-items-center"

>

<span

className={`todo-title mr-2 ${

this.state.viewCompleted ? "completed-todo" : ""

}`}

title={item.description}
>

{item.title}

</span>

</li>

));

};

render() {

return (

<main className="content">

<div className="row">

<div className="col-md-6 col-sm-10 mx-auto p-0">

<div className="card p-3">

<ul className="list-group list-group-flush">

{this.renderItems()}

</ul>

</div>

</div>

</div>

</main>

export default App;


Let’s go through each line of code to better understand what they do:

In our constructor, we created a few properties in our state object. We assigned the viewCompleted property
to false since our interface only shows items marked as not complete from our API at the moment.

The activeItem property includes the title, description and passes false to completed as the default status.

We then pass an empty array to our todoList because we are going to fetch our data from an API.

First, we wrap fetch() in a try/catch block to handle any network errors. We then call fetch() with
the await keyword, where we pass our API endpoints.

The async enables asynchronous operations, it returns a resolve value promise from our function.

We will define the componentDidMount() method as part of the async function. This enables us to perform
each fetch using the await keyword.

The componentDidMount() function is called by React when a component is rendered on the client-side. Read
more about life cycle functions from this article.

The setState() method in the componentDidMount() function is called when we want to update a change to
our previous state in the application.

We create a renderItems() function that uses the filter built-in array functionality, to show the completed
items from our todoList. The filter function takes a function to evaluate each item in the list.

We define a variable newItems to store the items which we display by using the map functionality. We use a
ternary conditional operator to show if an item description is marked as complete or not.

Ternary is a JavaScript operator that returns true in the first condition and false in the second part of an
expression.

In our render() method we display the items through the renderItems() function.

The consumed data from the API should be displayed as follows:

To handle actions such as adding tasks and marking them complete, we can create a modal component.

Modal enables us to create custom content such as popovers or dialog boxes in our applications.

Let’s go ahead and create a components folder in the src directory then create a file in it called Modal.js:

mkdir src/components

cd components
touch Modal.js

Let’s add this to the file:

import React, { Component } from "react";

import {

Button,

Modal,

ModalHeader,

ModalBody,

ModalFooter,

Form,

FormGroup,

Input,

Label

} from "reactstrap";

export default class CustomModal extends Component {

constructor(props) {

super(props);

this.state = {

activeItem: this.props.activeItem

};

handleChange = e => {

let { name, value } = e.target;


if (e.target.type === "checkbox") {

value = e.target.checked;

const activeItem = { ...this.state.activeItem, [name]: value };

this.setState({ activeItem });

};

render() {

const { toggle, onSave } = this.props;

return (

<Modal isOpen={true} toggle={toggle}>

<ModalHeader toggle={toggle}>Todo Item</ModalHeader>

<ModalBody>

<Form>

<FormGroup>

<Label for="title">Title</Label>

<Input

type="text"

name="title"

value={this.state.activeItem.title}

onChange={this.handleChange}

placeholder="Enter Todo Title"

/>

</FormGroup>

<FormGroup>

<Label for="description">Description</Label>
<Input

type="text"

name="description"

value={this.state.activeItem.description}

onChange={this.handleChange}

placeholder="Enter Todo description"

/>

</FormGroup>

<FormGroup check>

<Label for="completed">

<Input

type="checkbox"

name="completed"

checked={this.state.activeItem.completed}

onChange={this.handleChange}

/>

Completed

</Label>

</FormGroup>

</Form>

</ModalBody>

<ModalFooter>

<Button color="success" onClick={() => onSave(this.state.activeItem)}>

Save

</Button>
</ModalFooter>

</Modal>

);

In the code above we first import React and the components from reactstrap that we installed earlier. In the
constructor, we use the property that we created earlier in the App.js file. The props keyword passes the
argument to the activeItem component as objects.

The handleChange method takes note of a change in the state of a React component, takes the event as a
parameter, and does something to change the state.

We use destructuring assignment to create a checkbox where users can click to mark a task as complete. We
then change the activeItem in our state object by setState() method.

In our render() method we pass toggle and the onSave() method to props. We return the Modal component
when toggled.

We add the toggle component in the ModalHeader to enable dropping the modal. In the ModalBody, we add
the forms for adding the item title and item description.

In each FormGroup, we specify the activeItem value. We use the onChange event to detect when the input
value changes and returns the target input’s name and value.

Since the last FormGroup’s input type is a checkbox the target value will be checked as we assigned it in
our handlechange() method.

In the ModalFooter we will create a button to save our items using the onSave() method.

We can then create the add task and mark as completed functionalities in App.js.

Before we continue let’s install axios. It allows our applications to make a request to external endpoints. We
use it to perform CRUD operations to our API.

npm install [email protected]

In the App.js add the code snippet below:

import React, { Component } from "react"

import Modal from "./components/Modal";

import axios from "axios";


class App extends Component {

state = {

viewCompleted: false,

activeItem: {

title: "",

description: "",

completed: false

},

todoList: []

};

async componentDidMount() {

try {

const res = await fetch('http://localhost:8000/api/todos/');

const todoList = await res.json();

this.setState({

todoList

});

} catch (e) {

console.log(e);

toggle = () => {
this.setState({ modal: !this.state.modal });

};

//Responsible for saving the task

handleSubmit = item => {

this.toggle();

if (item.id) {

axios

.put(`http://localhost:8000/api/todos/${item.id}/`, item)

return;

axios

.post("http://localhost:8000/api/todos/", item)

};

createItem = () => {

const item = {title: "", description: "", completed: false };

this.setState({ activeItem: item, modal: !this.state.modal });

};

displayCompleted = status => {

if (status) {

return this.setState({ viewCompleted: true});

return this.setState({ viewCompleted: false});


};

renderTabList = () => {

return (

<div className="my-5 tab-list">

<button

onClick={() => this.displayCompleted(true)}

className={this.state.viewCompleted ? "active" : ""}

>

Complete

</button>

<button

onClick={() => this.displayCompleted(false)}

className={this.state.viewCompleted ? "" : "active"}

>

Incomplete

</button>

</div>

);

};

renderItems = () => {

const { viewCompleted } = this.state;

const newItems = this.state.todoList.filter(

item => item.completed === viewCompleted

);
return newItems.map(item => (

<li

key={item.id}

className="list-group-item d-flex justify-content-between align-items-center"

>

<span

className={`todo-title mr-2 ${

this.state.viewCompleted ? "completed-todo" : ""

}`}

title={item.description}

>

{item.title}

</span>

</li>

));

};

render() {

return (

<main className="content">

<h1 className="text-white text-uppercase text-center my-4">Todo App</h1>

<div className="row">

<div className="col-md-6 col-sm-10 mx-auto p-0">

<div className="card p-3">

<div className="">
<button onClick={this.createItem} className="btn btn-success">Add Task</button>

</div>

{this.renderTabList()}

<ul className="list-group list-group-flush">

{this.renderItems()}

</ul>

</div>

</div>

</div>

{this.state.modal ? (

<Modal

activeItem={this.state.activeItem}

toggle={this.toggle}

onSave={this.handleSubmit}

/>

): null}

</main>

export default App;

First, import the Modal that we created earlier and axios. The toggle() method changes the Modal state when
toggled, if the expression is true it returns the properties defined in the Modal in Modal.js, otherwise nothing
happens. We add this in the render() method.

The handleSubmit() saves our items to the API, we use axios to make the requests to it. We use PUT to insert
the item into the already existing list of items according to the item id.
We then create a createItem() method to add our task which is defined in the render() method.

The displayCompleted() method checks the status of the viewCompleted we created in our state earlier and
returns true or false.

The renderTabList() method define two buttons Complete and Incomplete, if the viewCompleted() method
returns true, the item is Complete. If it returns false then the item is Incomplete. We had stated earlier how
the renderItems() method works.

Our render() method returns renderTabList(), renderItems() methods and the Add Task functionality which
uses the createItem() method to allow users to add task.

9.Create a custom server using http module and explore the other modules of Node JS like
OS, path, event.

To make HTTP requests in Node.js, there is a built-in module HTTP in Node.js to transfer
data over the HTTP. To use the HTTP server in the node, we need to require the HTTP
module. The HTTP module creates an HTTP server that listens to server ports and gives a
response back to the client.
Syntax:
const http = require('http');
Example 1: In this example, we can create an HTTP server with the help
of http.createServer() method.
Filename: max.js
 javascript

const http = require('http');

// Create a server

http.createServer((request, response) => {


// Sends a chunk of the response body

response.write('Hello World!');

// Signals the server that all of

// the response headers and body

// have been sent

response.end();

}).listen(3000); // Server listening on port 3000

Step to run this program: Run this max.js file using the below command:
node max.js
Output:
Console Output:

To make requests via the HTTP module http.request() method is used.


Syntax:
http.request(options[, callback])
Example 2: In this example, we will see to make requests via the HTTP
module http.request() method.
Filename: max.js
 javascript

const http = require('http');

let options = {
host: 'www.geeksforgeeks.org',

path: '/courses',

method: 'GET'

};

// Making a get request to

// 'www.geeksforgeeks.org'

http.request(options, (response) => {

// Printing the statusCode

console.log(`STATUS: ${response.statusCode}`);

}).end();

Step to run this program: Run this max.js file using the below command:
node max.js

Similar Reads
1.What are the differences between HTTP module and Express.js module ?

2.Will the 'error' event ever be emitted on 'http.IncomingMessage' in a node.js http.request ?

3.Why are HTTP cookies used by Node.js for sending and receiving HTTP cookies?

4.Different types of module used for performing HTTP Request and Response in Node.js

5.Node.js HTTP Module Complete Reference

6.Generating Errors using HTTP-errors module in Node.js


7.How to export promises from one module to another module node.js ?

8.How HTTP POST request work in Node.js?

9.HTTP Request vs HapiJS Request in Node.js

10.Node.js http.globalAgent Property

Related Tutorials
1.Onsen UI

2.React Material UI

3.NuxtJS

4.D3.js

5.Spectre CSS

10. Develop an express web application that can interact with REST API to perform CRUD
operations on student data. (Use Postman)

API mean Application Programming Interface, which is a set of clearly defined methods

of communication between the frontend and the database.

REST which stands for Representational State Transfer is an architectural style for

providing standards between computer systems on the web, making it easier for systems to

communicate with each other.

REST APIs mostly use JSON as the preferred choice for transferring data as they are easy to

understand and is readable.

In this tutorial, we will use Node, Express and MongoDB to create a REST API that would

support the four operations — GET, POST, PUT and DELETE.


So, let’s first discuss these four operations and try to understand what they mean in the

context of API development.

1. GET — GET means to read the data. The function of this operation is to retrieve the data
from the database and present it to the user.

2. POST — POST, as the name suggests, is used to post/add new data to the database. It
allows users to add new data to the database.

3. PUT — PUT means to update the data already present in the database.

4. DELETE — It is used to delete any existing data from the database.

So, our REST API will perform all these four operations. We will use the Express package to

make our work easier. We will use MongoDB as the NoSQL database to store all our data.

MongoDB stores data in JSON format.

So, we will do it step by step. First, we would build the API endpoints and then we would

connect to the database to perform actual operations. We would use Postman software for API

testing.

Setting up the Project

First of all, we need to download Node on our system. Then we can start creating our project.

So, first of all, we need to create a folder in our system where we would love to build our

project. I kept the name of the folder as rest-API.


Then we need to move into the rest-API folder we created just now. Now to start a new project,

we would run the following command within the folder:-

npm init

It will ask various questions regarding the project, like name, description and other things. We

want to keep everything in the default mode except the name and description, which we can

add at our convenience.

After completion, we will see a package.json file in the folder. It contains all the data we just

gave to create this file. You can see the entry point is the index.js file.

After creating the package.json file, we need to download Express on our machine. To install

Express, we can:-

npm install express --save

This will download and save express in our system and also will add express as a dependency

in our package.json file.

We will also like to download a development dependency named nodemon which will allow us

to develop faster. It will help us to avoid restarting the server each time we make a change and

will automatically refresh, which would save us a lot of time.

So, to install nodemon, we would do:


npm install --save-dev nodemon

Notice that we have used save-dev to install and add it in the package.json file as a dev

dependency, as we are using it to speed up our development process.

Now, we need to download MongoDB in our system and then create the cluster and connect it

with your local computer.

Next, we must download mongoose to interact with the MongoDB database from our express

application.

To install mongoose, do the following:

npm install mongoose --save

Now, we are ready to start building our REST API. Before starting, I would like to show

my package.json file so that you can verify everything is going perfectly.

"name": "rest-api",
"version": "1.0.0",
"description": "Test Rest API",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit
1"
},
"author": "Shubham",
"license": "ISC",
"dependencies": {
"express": "^4.17.1",
"mongoose": "^5.11.9"
},
"devDependencies": {
"nodemon": "^2.0.6"
}
}

So, let’s start building our REST API. First of all, we need to create a file named index.js; as we

can see, it is the entry point to our application.

The index file

We would start with the index.js file. We would start by requiring express into our system.

const express = require('express');

We will then set up our express app by writing the following line of code:-

const app = express();

So, then we would set up a GET function to test it using the browser. We pass a message as the

response when we have a GET request to localhost:4000/API.

app.get('/api', (req, res) => res.send('Its working!'));


We will then set up our application to start listening to the requests. We will use 4000 as the

port number. We have used the OR operator there so that if there is any port number defined

via environment variables, it could use that; otherwise, it will use 4000. You can choose the

port number as per your choice. We will console.log a message to check if it is working

properly.

app.listen(process.env.port || 4000, function(){


console.log('now listening for requests');
});

So, when we would start the server now using:

nodemon index

When we go to localhost:4000/api, we would see the message ‘It’s working!’. Also, in the
console, we would get the message we set for the console.

So, here we are, with the express server set up properly, and we sent our first GET request

successfully.

Now, we would like to have all four operations in a separate file called api.js under

the routes folder, as we want to avoid pushing everything into the index.js file.

So, we would remove the app.get part in this index.js file. We want to add the mongoose as a

requirement in our file.


const mongoose = require('mongoose');

Next, below the set-up of our express app, we would like to connect to MongoDB. We would do

so with the following code:

mongoose.connect('mongodb://localhost/ourdata');
mongoose.Promise = global.Promise;

Here, ourdata is the name of the model we will be creating in MongoDb later in this tutorial.

We also updated the promises of the mongoose as the global promise since

the mongoose.promise is depreciated now.

Next, we would add a few more middlewares in the file. We would first add support to serve

static files. Though we won't be serving static files in this tutorial but having it is nice since we

would need to add a frontend anyway later on to use the APIs.

app.use(express.static('public'));

We would then add the Express parser to parse the data sent or received from the database.

app.use(express.json());

We then set up the app to use the new api.js file we would create to hold all four operations.
app.use('/api',require('./routes/api'));

We have added ‘/api’ in the starting to avoid adding it to all four of the operations.

Finally, we added a middleware to handle the errors that occurred during the operations.

app.use(function(err,req,res,next){
res.status(422).send({error: err.message});
});

Here is the finalized code for the index.js file:-

const express =
require('express')
;
const mongoose = require('mongoose');
// set up our express app
const app = express();
// connect to mongodb
mongoose.connect('mongodb://localhost/
ourdata');
mongoose.Promise = global.Promise;
app.use(express.static('public'));
app.use(express.json());
// initialize routes
app.use('/api',require('./routes/api'));
// error handling middleware
app.use(function(err,req,res,next){
//console.log(err);
res.status(422).send({error: err.message});
});
// listen for requests
app.listen(process.env.port || 4000, function()
{
console.log('Ready to Go!');
});

The layout of the four CRUD operations

Next up, we create a folder named router and create a new file named api.js inside the folder.

This would hold all four CRUD operations we want to do with the REST API we are building.

We first start by requiring express in our file. Then we would create a router using the express
router.

const express = require('express');


const router = express.Router();

So, let’s start building the four operations one by one. We would not be saving anything to the

database since we have not created one yet, but we would be testing them more simply.

So, we would start with the GET operator. We will write the code for the GET request in this

way:-

router.get('/students',function(req,res){
res.send({type: 'GET'});
};

Here, we are giving the endpoint and a function which gives a response which tells the type of

the request sent.


Next up is the POST request. It will be in a similar way though we would like to return the

data which we received from the request.

router.post('/students', function(req, res){


res.send({
type: 'POST',
name: req.body.name,
roll: req.body.roll
});
});

Next up is the PUT and DELETE request. For now, we would return the type of request for

both operations. It accepts the endpoint with an id which denotes the unique id which

MongoDB provides when we save data to it.

router.put('/students/:id', function(req, res){


res.send({type: 'PUT'});
});

router.delete('/students/:id', function(req, res){


res.send({type: 'DELETE'});
});

Next, we would export the module to be used within the index.js file.

module.exports = router;

To test out these operations, we would use a software called Postman. It is amazing and helps

to test out APIs really fast.


Download the Postman desktop agent or install its Chrome extension to start using Postman.

A Postman new Workspace looks like the following:-

Postman API Testing

Here, we can choose the type of operation and the target URL for sending requests. For POST

requests, we need to send some JSON data while sending requests which we can be done by

adding the JSON in the Body section.

You need to select Raw data type and then choose JSON as the format such as shown below:-

Postman POST request

So, we can test all these operations via Postman very easily. We also need to provide the data

while PUT requests as we are updating the data. We only pass the data we need to update.

Building the Database Schema and Model

Next, we would create a folder named models and then create a student.js file within that

folder.

We would require mongoose in that folder and would build a Schema and then a model based

on that Schema. A Schema tells the model how the data is to be structured.

We are building a model which would contain data of the students — name, their roll number

and whether they are present or not.

1. Name — This is of String data type and is not a required field in the Schema.
2. Roll — This is also of String data type and is a required field. It cannot be left empty.

3. Present — This is a Boolean field which defaults to true.

We then created the model named Student with the help of the StudentSchema that we

created. We then export the model to use it in the API file.

So, let’s have a look at the student.js file:-

const mongoose =
require('mongoose');
const Schema = mongoose.Schema;
// create student schema & model
const StudentSchema = new Schema({
name: {
type: String,
},
roll: {
type: String,
required: [true, 'Roll field is required']
},
present: {
type: Boolean,
deafult: true
}
});
const Student =
mongoose.model('student',StudentSchema);
module.exports = Student;

Finalizing the api.js file

Now, we would make all four API endpoints usable by saving and retrieving data from the

database model we created.


So, we need to require that database model in the API file.

const Student = require('../models/student');

We then start with the GET request. We would get all the students in our database and send

them all as a response. You can add any sort of filtering for the students, but we are leaving the

find function empty to access every student from the database. We then use

the .catch(next) function to help catch any errors and pass it to the next middleware — error

handling middleware in our case.

router.get('/students',function(req,res,next){
Student.find({}).then(function(students){
res.send(students);
}).catch(next);
});

Next, we go for the POST request. We create a new student in the database and then return the

created student as a response.

router.post('/students',function(req,res,next){
Student.create(req.body).then(function(student){
res.send(student);
}).catch(next);
});

Next, we have the PUT request. We would use the findOneAndUpdate function to find the

corresponding entry in the database using the id we passed in the URL endpoint. We then find

the same student with the help of their Id and return the updated student as a response.
router.put('/students/:id',function(req,res,next){
Student.findOneAndUpdate({_id:
req.params.id},req.body).then(function(student){
Student.findOne({_id: req.params.id}).then(function(student){
res.send(student);
});
});
});

Lastly, we have the DELETE request. We use the function findOneAndDelete to find the

corresponding student in the database via the id provided and delete that student from the

database. It also returns the deleted student as a response.

router.delete('/students/:id',function(req,res,next){
Student.findOneAndDelete({_id: req.params.id}).then(function(student){
res.send(student);
});
});

We can test all these using the Postman software very easily. Everything should work fine on

testing, and we have done everything nicely and cleanly.

Here is the final code for the api.js file:-


const express =
require('express');
const router = express.Router();
const Student = require('../models/student');
// get a list of students from the database
router.get('/students',function(req,res,next){
Student.find({}).then(function(students){
res.send(students);
}).catch(next);
});
// add a new student to database
router.post('/students',function(req,res,next){
Student.create(req.body).then(function(student){
res.send(student);
}).catch(next);
});
// update a student in the database
router.put('/students/:id',function(req,res,next){
Student.findOneAndUpdate({_id:
req.params.id},req.body).then(function(student){
Student.findOne({_id:
req.params.id}).then(function(student){
res.send(student);
});
});
});
// delete a student in the database
router.delete('/students/:id',function(req,res,next){
Student.findOneAndDelete({_id:
req.params.id}).then(function(student){
res.send(student);
});
});
module.exports = router;

11. For the above application create authorized end points using JWT (JSON Web Token).

What JSON Web Tokens (JWT)?

JSON Web Token is a open standard for transferring authorization details between client and

server. In JWT all the information is self contained, we don’t need to store them in server.

For Example: A user comes to our web application and login with username and password.

After verifying the credentials, sever provides the two JSON web tokens. One of them is an
Access Token and other is Refresh Token. After get the token server stores the token and pass

the access token in the authorization header. The server verify the token and identify the user.

Access token is valid for short time (depending on the configurations). In such a case if token

is invalid or expire, we will use the refresh token to generate the new access token.

Backend — Django

First, We will set up the project.

Create the Virtual environment:


## Create the Virtual Environment.python -m venv <Virtual Environment
Name>

Activate the Virtual environment:


# Activate the Virtual Environment.<Virtual Environment Name>\scripts\
activate

If you found any error to activate the virtual environment run the command before activate

the virtual environment:


Set-ExecutionPolicy Unrestricted -Scope Process

After activate the virtual environment, we install the packages such as Django, Django REST

framework, Django REST framework simple JWT and Django CORS headers. The DRF

packages is used to create the API, while DRF simple JWT gives as ability to generate the JWT

Token and Django CORS headers is used to avoid CORS related issues.
# Python Packagespip install Django
pip install djangorestframework
pip install djangorestframework-simplejwt
pip install django-cors-headers
Once this is done, We will create the Project.
# Create the Project.django-admin startproject backend

Then, we will create the first app inside the project.


# Create the app.python manage.py startapp authentification

Now, we have to change the project setting. Go into settings.py file and make the following

modifications:
from datetime import timedelta.....INSTALLED_APPS = [
...........
# Register your app
'corsheaders',
'rest_framework',
'rest_framework_simplejwt.token_blacklist'
].....CORS_ORIGIN_ALLOW_ALL = True.....MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
...........
].....REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework_simplejwt.authentication.JWTAuthentication',
],
}.....SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(minutes=10),
'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
'ROTATE_REFRESH_TOKENS': True,
'BLACKLIST_AFTER_ROTATION': True
}

Let’s look what we have done. First, we have register our app name (You will write your app

name), DRF, DRF simple JWT and CORS in INSTALLED_APPS. Second, we have set the

CORS_ORIGIN_ALLOW_ALL = True and added the custom CORS header middleware in

MIDDLEWARE to avoid the CORS related issue. Then, we have added the authentication JWT

Class in REST_FRAMEWORK and added the SIMPLE_JWT token configurations to

implement an access/refresh logic.


After add the configuration in settings.py file, we will create the URL for access token and

refresh token in backend/urls.py file.


from django.contrib import admin
from django.urls import path, include
from rest_framework_simplejwt import views as jwt_viewsurlpatterns = [
.....
path('token/',
jwt_views.TokenObtainPairView.as_view(),
name ='token_obtain_pair'),
path('token/refresh/',
jwt_views.TokenRefreshView.as_view(),
name ='token_refresh')
]

Now, we are almost ready to test whether it is works or not. Before run the project we have to

apply the migration and create the user. Run this command to apply the migration:
# Apply the migration.python manage.py migration

Once this is done. we will create the user using this command:
# Create the user.python manage.py createsuperuser

Fill all the fields and now, we will start the development server using this command:
# Runserverpython manage.py runserver

After run the server, we will navigate to this http://localhost:8000/token/, we will see this

page which contains the form with username and password field.

Fill this form with your created username and password, you should see the access and refresh

token.

We all know, access token is invalid after some time. So by the use of refresh token we will

generate the new access token and refresh token as well. To generate the new access token
with the help of refresh token, we will navigate to this

URL http://localhost:8000/token/refresh/, we will see this page which contains the form with

Refresh field.

Fill this form with Refresh Token, you should see the new access and refresh token.

Now, we will create the views for testing. so, we will go in views.py file in our app directory and

write the following code:


from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticatedclass
HomeView(APIView):

permission_classes = (IsAuthenticated, ) def get(self, request):


content = {'message': 'Welcome to the JWT
Authentication page using React Js and Django!'}
return Response(content)

Let’s look what we have done. First, we have import the modules and created the class based

view using simple APIView then, we have set the permission class for authenticated user.

Second, we have created the get method and set the response.

Now, we will create the URL for HomeView. To create the URL first, we have to create the

urls.py file in our app directory.


from django.urls import path
from . import viewsurlpatterns = [
path('home/', views.HomeView.as_view(), name ='home')
]

Second, we have to register the urls.py file path in our project directory urls.py file.
urlpatterns = [
......
path('', include('<app name>.urls')),
]
Now, we will use the POSTMAN to hit this URL http://localhost:8000/home/ with get

request and we get authentication credential not provided message because in our HomeView

we have set the permission class is IsAuthenticated means this page is only for authenticated

user.

So, we have to provide the access token in authorization to get the result. Now again, we will

create the get request with access token. To set the access token in POSTMAN, we have to click

on Authorization button and set the token type is Bearer Token and paste the access token.

After hit the API we will get this output:

Now, we have to add the logout functionality because we all know access token is valid for

some time.

By the use of refresh token, we will generate the new access token. But, what happens when

user wants to log out. The client can forgot both token. For example we have remove both the

access and refresh token from localStorage. But, if refresh token is stolen, then another client

use this token and use it. To prevent this, we will create the logout API, by using we can invalid

the refresh token.

To create logout API, we will write the LogoutView in our views.py file in app directory:
class LogoutView(APIView): permission_classes = (IsAuthenticated,)
def post(self, request):

try: refresh_token =
request.data["refresh_token"] token =
RefreshToken(refresh_token) token.blacklist()
return Response(status=status.HTTP_205_RESET_CONTENT) except
Exception as e: return
Response(status=status.HTTP_400_BAD_REQUEST)
After create the LogoutView, we have to create the URL for LogoutView in our urls.py file in

app directory.
urlpatterns = [
.....
path('logout/', views.LogoutView.as_view(), name ='logout')
]

By using that URL http://localhost:8000/logout/, we can invalid the refresh token and add

token into blacklist. By using Postman we can hit this URL with POST request and pass the

access token in authorization and refresh token in body.

Now all things is set on backend, We have tested all the API’s.

Frontend — React JS

There are many ways to connect the Django to your frontend but, In this tutorial we design the

frontend using React JS Framework. We have already created the API’s for authentication.

Let’s setup the React app using this command:


// Create the react app.npx create-react-app frontend

Install the following packages:


// Install the packages.
npm i bootstrap
npm i axios
npm i react-router-dom

After setup the project run this command to run the react app:
# To run the react app.npm start
Then open http://localhost:3000/ to see your app.

After run the server successfully, we move further to design the application. So first, we will

create the component folder inside the src folder.

After create the component folder in src we will create the login.js, logout.js, navigation.js and

home.js. Basically, we have created the different file for different use.

So first, we will write the code for navigation bar in navigations.js file.
import Nav from 'react-bootstrap/Nav';
import Navbar from 'react-bootstrap/Navbar';
import React, { useState, useEffect} from 'react';export function
Navigation() { const [isAuth, setIsAuth] = useState(false);
useEffect(() => { if (localStorage.getItem('access_token') !==
null) { setIsAuth(true);
} }, [isAuth]); return (
<div>
<Navbar bg="dark" variant="dark">
<Navbar.Brand href="/">JWT Authentification</Navbar.Brand>

<Nav className="me-auto">
{isAuth ? <Nav.Link href="/">Home</Nav.Link> : null}
</Nav>
<Nav>
{isAuth ? <Nav.Link href="/logout">Logout</Nav.Link> :
<Nav.Link href="/login">Login</Nav.Link>}
</Nav>
</Navbar>
</div>
);
}

To deign the navigation page. First, we have imported all the packages and then define

Navigation function. Inside the navigation function, we have used the useState to store the

value in isAuth variable. Initially, we have set the value false. Then, used the useEffect and
check access token is present or not in localStoarge. if it is not present than change isAuth

variable value from false to true.

Then, we have return the HTML code to design the navigation bar and used the ternary

operator condition which check isAuth is true or false. if it is then, it shows the Home and

Logout button on navigation bar otherwise it show login button like this:

After written navigation page code, we have to add route condition in our app.js file.
import './App.css';
import {BrowserRouter, Routes, Route} from 'react-router-dom'
import {Login} from "./component/login";
import {Home} from "./component/Home";
import {Navigation} from './component/navigation';
import {Logout} from './component/logout';function App() { return
<BrowserRouter>
<Navigation></Navigation>
<Routes>
<Route path="/" element={<Home/>}/>
<Route path="/login" element={<Login/>}/>
<Route path="/logout" element={<Logout/>}/>
</Routes>
</BrowserRouter>;
}
export default App;

In App.js file first, we have imported all the packages and files, then, written the route
condition for login, logout and home page.

After design the Navigation, we will write the code for login functionality in login.js file.

// Import the react JS packages


import axios from "axios";
import {useState} from "react";// Define the Login function.
export const Login = () => { const [username, setUsername] =
useState(''); const [password, setPassword] = useState(''); //
Create the submit method.
const submit = async e => { e.preventDefault();
const user = {
username: username,
password: password
}; // Create the POST requuest
const {data} = await

axios.post('http://localhost:8000/token/',
user ,{headers:
{'Content-Type': 'application/json'}},
withCredentials: true});
// Initialize the access & refresh token in localstorage.

localStorage.clear();
localStorage.setItem('access_token', data.access);
localStorage.setItem('refresh_token', data.refresh);
axios.defaults.headers.common['Authorization'] =
`Bearer ${data['access']}`;
window.location.href = '/' } return( <div className="Auth-
form-container">
<form className="Auth-form" onSubmit={submit}>
<div className="Auth-form-content">
<h3 className="Auth-form-title">Sign In</h3>
<div className="form-group mt-3">
<label>Username</label>
<input className="form-control mt-1"
placeholder="Enter Username"
name='username'
type='text' value={username}
required
onChange={e => setUsername(e.target.value)}/>
</div>
<div className="form-group mt-3">
<label>Password</label>
<input name='password'
type="password"
className="form-control mt-1"
placeholder="Enter password"
value={password}
required
onChange={e => setPassword(e.target.value)}/>
</div>
<div className="d-grid gap-2 mt-3">
<button type="submit"
className="btn btn-primary">Submit</button>
</div>
</div>
</form>
</div>
)
}

Let’s look what we have done. First, we have initialize the react js packages. Second, we have

create the function which name is Login. Inside the login function we have created the submit

function. Inside the submit function we have written the axios post method to fetch the access

token and refresh token. After fetch the token, we have store this tokens in local storage and

navigate to the particular location which you want. For this case, I have route to my home

URL. Then, we have design the Login form with username and password fields. Whenever, we

click on submit button, the submit function is called and fetch the data from our backend login

API. If it is successful than we get the access token and navigate to other page or home page

otherwise it gives error in console.

After design the login page our page looks like:

After design the Login page, let’s move on to write the code for home page in our home.js file.
// Import the react JS packages
import {useEffect, useState} from "react";
import axios from "axios";
// Define the Login function.
export const Home = () => { const [message, setMessage] =
useState(''); useEffect(() =>
{ if(localStorage.getItem('access_token') === null){
window.location.href = '/login'
}
else{ (async () => { try { const
{data} = await axios.get(
'http://localhost:8000/home/', {
headers: {
'Content-Type': 'application/json'
}}
); setMessage(data.message);
} catch (e) { console.log('not auth')
} })()}; }, []); return <div
className="form-signin mt-5 text-center">
<h3>Hi {message}</h3>
</div>
}

Let’s look what we have done. First, we have initialize the react js packages. Second, we have

create the function which name is Home. Inside the Home we have used the useState to store

the message data and useEffect which called when every time the component renders. Inside

useEffect we have written if else condition to check the access token is present or not. If access

token is null in localStorage then, we will redirect to login page otherwise if we have token, we

will create the get request to fetch the data from home API and set the message. Then, We

have written the HTML code to display the message and our home page looks like:

We have design the home page also but, we all know that our access token is valid for very

short time. After short time when we refresh the page, we will get the 401 unauthorized error

because our access token is invalid. But we also know that in backend, we have created the

refresh token API, which will generate the new access token and refresh token.

But the problem is how we know or after how much time access token is invalid or not. To

resolve this problem, we use the interceptor in react js or in other words we can say

middleware.

Basically, Interceptors are methods which are triggered before or after the main method. So in

this case we have using the axios interceptor. There are two types of interceptors:
1. Request interceptor: — It allows you to write or execute your code before the request gets
sent.

2. Response interceptor: — It allows you to write or execute your code before response
reaches the calling end.

So in our case, we have using the response interceptor because, we have to check the response.

To write the response interceptor code first, we make the interceptor folder. Inside the

interceptor folder create the axiox.js file. Inside the axios.js file, we will write the code:
import axios from "axios";let refresh =
false;axios.interceptors.response.use(resp => resp, async error =>
{ if (error.response.status === 401 && !refresh) { refresh = true;
console.log(localStorage.getItem('refresh_token'))
const response = await
axios.post('http://localhost:8000/token/refresh/', {
refresh:localStorage.getItem('refresh_token')
}, { headers:
'Content-Type': 'application/json'
}
},{withCredentials: true}); if
(response.status === 200) {
axios.defaults.headers.common['Authorization'] = `Bearer
${response.data['access']}`;
localStorage.setItem('access_token', response.data.access);
localStorage.setItem('refresh_token', response.data.refresh);
return axios(error.config);
} }
refresh = false;return error;});

Let’s look what we have done. First, we have import the axios package and then, create the

axios response interceptor. Now, Every single time a request is made with the axios instance, if

there are no errors, it just works as expected.

When there is error occur first, we will check the error code. If the error code is 401, we need

to refresh the token. To refresh the token, we will create the POST request and get the new
access token and refresh token. After get the token, we will reinitialize the token in

localStorage and send the original request.

After create the response interceptor. We have to the add the interceptor location in our

index.js file.
import './interceptors/axios';

Now, we will write the code for logout functionality in logout.js file.
import {useEffect, useState} from "react"
import axios from "axios";export const Logout = () => { useEffect(()
=> { (async () => { try {
const {data} = await
axios.post('http://localhost:8000/logout/',{
refresh_token:localStorage.getItem('refresh_token')
} ,{headers: {'Content-Type': 'application/json'}},
{withCredentials: true});
localStorage.clear();\
axios.defaults.headers.common['Authorization'] = null;
window.location.href = '/login'
} catch (e) {
console.log('logout not working', e)
}
})();
}, []); return (
<div></div>
)
}

To add the logout functionality, we have declares the packages and use the useEffect hooks.

Whenever we click on logout button, it call the backend logout API and remove all the tokens

from local storage and navigate to login page.

12. Create a react application for the student management system having registration, login,
contact, about pages and implement routing to navigate through these pages.
Creating a registration form
The registration form is divided into two components in this tutorial i.e. Header and registrationForm,
which will be rendered in App.js.

Create a new folder named components inside the src folder. In the components folder following files
will be created:

header.js
registrationForm.js
style.css
Note: In react, JSX is used instead of HTML code. JSX is a markup language that contains HTML &
JavaScript.

In the header.js write the following code. You can copy-paste from here as well.

import React from 'react';


function Header() {
return(
<nav class="bg-dark navbar-dark navbar">
<div className="row col-12 d-flex justify-content-center text-white">
<h3>Registration</h3>
</div>
</nav>
)
}
export default Header;
Now, your header is ready. To display it on the website you have to import the header.js in App.js.
Write the following code in the App.js.

import logo from './logo.svg';


import './App.css';
import Header from './components/header';

function App() {
return (
<div className="App">
<Header/>
</div>
);
}

export default App;

If you have written the above code correctly the webpage will look like this:
header;

Moving forward to the next component i.e. registrationForm.

It contains the following fields:

First Name
Last Name
Email id
Password
Confirm Password
Submit Button
Next, write the following code in the registrationForm.js to create the form body.

import React, {useState} from 'react';


import './style.css'
function RegistrationForm() {
return(
<div className="form">
<div className="form-body">
<div className="username">
<label className="form__label" for="firstName">First Name </label>
<input className="form__input" type="text" id="firstName" placeholder="First Name"/>
</div>
<div className="lastname">
<label className="form__label" for="lastName">Last Name </label>
<input type="text" name="" id="lastName"
className="form__input"placeholder="LastName"/>
</div>
<div className="email">
<label className="form__label" for="email">Email </label>
<input type="email" id="email" className="form__input" placeholder="Email"/>
</div>
<div className="password">
<label className="form__label" for="password">Password </label>
<input className="form__input" type="password" id="password"
placeholder="Password"/>
</div>
<div className="confirm-password">
<label className="form__label" for="confirmPassword">Confirm Password </label>
<input className="form__input" type="password" id="confirmPassword"
placeholder="Confirm Password"/>
</div>
</div>
<div class="footer">
<button type="submit" class="btn">Register</button>
</div>
</div>
)
}
export default RegistrationForm;
Your basic form structure is ready but needs some styling. To style your form, write the following
code in style.css.

Note: Don’t forget to import style.css in registrationForm.js. In this tutorial, it has already been added.

body{
background: #bdc3c7; /* fallback for old browsers */
background: -webkit-linear-gradient(to right, #2c3e50, #bdc3c7); /* Chrome 10-25, Safari 5.1-6 */
background: linear-gradient(to right, #2c3e50, #bdc3c7); /* W3C, IE 10+/ Edge, Firefox 16+,
Chrome 26+, Opera 12+, Safari 7+ */
}

.form{
background-color: white;
border-radius: 5px;
width: 550px;
margin: 20px auto;
padding: 20px;
/* height: 600px; */
}

.form-body{
text-align: left;
padding: 20px 10px;
}

.form-body > *{
padding: 5px;
}

.form__label{
width: 40%;
}

.form_input{
width: 60%;
}

.footer{
text-align: center;
}
Add this component in App.js.

import logo from './logo.svg';


import './App.css';
import Header from './components/header';
import RegistrationForm from './components/registrationForm'

function App() {
return (
<div className="App">
<Header/>
<RegistrationForm/>
</div>
);
}

export default App;

Implementing hooks in registration form


In this section, you will have an overview of hooks in react.js. For more details I recommend you to
first go through react official documentation.

useState hook is used to maintain a state of a variable which you can update dynamically using
setState.

Now get to your form where you need to maintain the state of every input in the form. So that when
users hit submit button you can send the data to the backend API. In vanilla JavaScript it is done using
document.getElementById("demo").value while in react we will have a state for every input and
update it on every onChange event.

Import useState and setState hooks from react at top of our code. Now we can make a state for all
input elements.

const [firstName, setFirstName] = useState(null);


const [lastName, setLastName] = useState(null);
const [email, setEmail] = useState(null);
const [password,setPassword] = useState(null);
const [confirmPassword,setConfirmPassword] = useState(null);

We will add two attributes in the input tag to maintain the state variable i.e.
Value onChange
Value: The value attribute will contain the name of the fields, that we used while declaring states.

onChange: Write the following code for onChange attribute.

onChange = {(e) => handleInputChange(e)}


<input className="form__input" type="text" value={firstName} onChange = {(e) =>
handleInputChange(e)} id="firstName" placeholder="First Name"/>
<input type="text" name="" id="lastName" value={lastName} className="form__input" onChange
= {(e) => handleInputChange(e)} placeholder="LastName"/>
<input type="email" id="email" className="form__input" value={email} onChange = {(e) =>
handleInputChange(e)} placeholder="Email"/>
<input className="form__input" type="password" id="password" value={password} onChange =
{(e) => handleInputChange(e)} placeholder="Password"/>
<input className="form__input" type="password" id="confirmPassword" value={confirmPassword}
onChange = {(e) => handleInputChange(e)} placeholder="Confirm Password"/>
In the code below, inside the onChange event call the function handleInputChange that will handle
state updates of all the input changes.

const handleInputChange = (e) => {


const {id , value} = e.target;
if(id === "firstName"){
setFirstName(value);
}
if(id === "lastName"){
setLastName(value);
}
if(id === "email"){
setEmail(value);
}
if(id === "password"){
setPassword(value);
}
if(id === "confirmPassword"){
setConfirmPassword(value);
}

}
In this function, you get the id and the value entered inside the input box, as soon as you type anything
there, the state of that particular field will get updated. This is how you will maintain all the states so
that on submit button you can send all the required information to the backend APIs.
In this tutorial handleSubmit function is used in which you will get all the values that are filled in the
form. This function will be used to connect the app with the firebase. This is the final code for the
registration form which includes all the details you learned above in the tutorial so far.

import React, {useState,setState} from 'react';


import './style.css'
function RegistrationForm() {

const [firstName, setFirstName] = useState(null);


const [lastName, setLastName] = useState(null);
const [email, setEmail] = useState(null);
const [password,setPassword] = useState(null);
const [confirmPassword,setConfirmPassword] = useState(null);

const handleInputChange = (e) => {


const {id , value} = e.target;
if(id === "firstName"){
setFirstName(value);
}
if(id === "lastName"){
setLastName(value);
}
if(id === "email"){
setEmail(value);
}
if(id === "password"){
setPassword(value);
}
if(id === "confirmPassword"){
setConfirmPassword(value);
}

const handleSubmit = () => {


console.log(firstName,lastName,email,password,confirmPassword);
}

return(
<div className="form">
<div className="form-body">
<div className="username">
<label className="form__label" for="firstName">First Name </label>
<input className="form__input" type="text" value={firstName} onChange = {(e) =>
handleInputChange(e)} id="firstName" placeholder="First Name"/>
</div>
<div className="lastname">
<label className="form__label" for="lastName">Last Name </label>
<input type="text" name="" id="lastName" value={lastName}
className="form__input" onChange = {(e) => handleInputChange(e)} placeholder="LastName"/>
</div>
<div className="email">
<label className="form__label" for="email">Email </label>
<input type="email" id="email" className="form__input" value={email} onChange =
{(e) => handleInputChange(e)} placeholder="Email"/>
</div>
<div className="password">
<label className="form__label" for="password">Password </label>
<input className="form__input" type="password" id="password" value={password}
onChange = {(e) => handleInputChange(e)} placeholder="Password"/>
</div>
<div className="confirm-password">
<label className="form__label" for="confirmPassword">Confirm Password </label>
<input className="form__input" type="password" id="confirmPassword"
value={confirmPassword} onChange = {(e) => handleInputChange(e)} placeholder="Confirm
Password"/>
</div>
</div>
<div class="footer">
<button onClick={()=>handleSubmit()} type="submit" class="btn">Register</button>
</div>
</div>

)
}

13. Create a service in react that fetches the weather information from open weather map.org and the
display the current and historical weather information using graphical representation using chart.js.

How to Create the Weather Components


Let's create our weather components where we will display our weather data.

In your src folder, create a folder called components, and in that folder, create a file
called weather.js.

Now, let's call our weather component in our main app.js file.
import './App.css';
import React, { useEffect, useState } from "react";
import Weather from './components/weather';
export default function App() {

const [lat, setLat] = useState([]);


const [long, setLong] = useState([]);
const [data, setData] = useState([]);

useEffect(() => {
const fetchData = async () => {
navigator.geolocation.getCurrentPosition(function(position) {
setLat(position.coords.latitude);
setLong(position.coords.longitude);
});

await fetch(`${process.env.REACT_APP_API_URL}/weather/?lat=${lat}&lon=$
{long}&units=metric&APPID=${process.env.REACT_APP_API_KEY}`)
.then(res => res.json())
.then(result => {
setData(result)
console.log(result);
});
}
fetchData();
}, [lat,long])

return (
<div className="App">
{(typeof data.main != 'undefined') ? (
<Weather weatherData={data}/>
): (
<div></div>
)}
</div>
);
}
Importing Weather Component in app.js file

You can see that I've included a check in the return statement. If the type of data we are
getting is undefined, it will show us an empty div. And since the fetch data is an async
function, it's mandatory to include this check. It loads the function after all other functions are
done executing. So, if you remove this check, you will get an error.

This is because our application renders the return statement before the API call is made, and
there is nothing to show in that case so it throws an undefined error.

To learn more about async/await, check out this article.


How to Create our Weather Body
For this part, we are going to use the Semantic UI library to design our interface.

Let's create a card that will display our weather information.

import React from 'react';


import './styles.css';
import { Card } from 'semantic-ui-react'

const CardExampleCard = ({weatherData}) => (


<Card>
<Card.Content>
<Card.Header
className="header">{weatherData.name}</Card.Header>
</Card.Content>
</Card>
)

export default CardExampleCard;


Weather.js

Here, we import a card from semantic-ui-react, and inside that card, a header that will show
the name of your city.
But the question is, how do we get data from our app.js to the weather.js component?

The answer is simple. We can use props in React to send data from a parent component to a
child component. In our case, our parent component is app.js and our child component is
weather.js.

And to do that, just add the props in the component in app.js.


<Weather weatherData={data}/>
Here, we are passing the data with the props name as weatherData. And we will receive the
weatherData props in Weather.js.
import React from 'react';
import './styles.css';
import { Card } from 'semantic-ui-react'

const CardExampleCard = ({weatherData}) => (


<Card>
<Card.Content>
<Card.Header className="header">{weatherData.name}</Card.Header>
</Card.Content>
</Card>
)

export default CardExampleCard;

You can see we get the name of the city according to the location.

Similarly, we can add more fields to our weather component.

import React from 'react';


import './styles.css';
import { Card } from 'semantic-ui-react'

const CardExampleCard = ({weatherData}) => (


<Card>
<Card.Content>
<Card.Header className="header">City Name:
{weatherData.name}</Card.Header>
<p>Temprature: {weatherData.main.temp}</p>
<p>Sunrise: {weatherData.sys.sunrise}</p>
<p>Sunset: {weatherData.sys.sunset}</p>
<p>Description: {weatherData.weather[0].description}</p>
</Card.Content>
</Card>
)

export default CardExampleCard;


We can get the Temperature, Sunrise, Sunset, and Description from the API.

You can add any other fields you want, like Humdity, Windspeed, Visibility, and more.

How to Format the Data and Add Today's Day and Date
Let's format the data so that it's easy to understand. We will add some more fields.

To start, add the unit of temperature. You can do this by adding &deg;C after the
temperature.
Also, let's change sunrise and sunset to local time.

import React from 'react';


import './styles.css';
import { Card } from 'semantic-ui-react'

const CardExampleCard = ({weatherData}) => (


<Card>
<Card.Content>
<Card.Header className="header">City Name:
{weatherData.name}</Card.Header>
<p>Temprature: {weatherData.main.temp} &deg;C</p>
<p>Sunrise: {new Date(weatherData.sys.sunrise *
1000).toLocaleTimeString('en-IN')}</p>
<p>Sunset: {new Date(weatherData.sys.sunset *
1000).toLocaleTimeString('en-IN')}</p>
<p>Description: {weatherData.weather[0].main}</p>
<p>Humidity: {weatherData.main.humidity} %</p>
</Card.Content>
</Card>
)

export default CardExampleCard;


Now, let's add today's day and date using moment.js.
import moment from 'moment';

<p>Day: {moment().format('dddd')}</p>
<p>Date: {moment().format('LL')}</p>
Using moment.js

We import the moment package at the top and display today's day and date respectively. The
great thing about this package is that it automatically updates the date and the day.
This is how our weather.js look like now:
import React from 'react';
import './styles.css';
import { Card } from 'semantic-ui-react';
import moment from 'moment';

const CardExampleCard = ({weatherData}) => (


<Card>
<Card.Content>
<Card.Header className="header">City Name:
{weatherData.name}</Card.Header>
<p>Temprature: {weatherData.main.temp} &deg;C</p>
<p>Sunrise: {new Date(weatherData.sys.sunrise *
1000).toLocaleTimeString('en-IN')}</p>
<p>Sunset: {new Date(weatherData.sys.sunset *
1000).toLocaleTimeString('en-IN')}</p>
<p>Description: {weatherData.weather[0].main}</p>
<p>Humidity: {weatherData.main.humidity} %</p>
<p>Day: {moment().format('dddd')}</p>
<p>Date: {moment().format('LL')}</p>
</Card.Content>
</Card>
)

export default CardExampleCard;


weather.js

And the above is our output.

Let's Do Some Styling


Now that we have all our data, let's style them to make it more attractive.

First of all, let's make the card bigger, change the border-radius, add a cooler font and a
color, and remove the text alignment.

import React from 'react';


import './styles.css';
import moment from 'moment';

const CardExampleCard = ({weatherData}) => (


<div className="main">
<p className="header">{weatherData.name}</p>
<div>
<p className="day">Day: {moment().format('dddd')}</p>
</div>

<div>
<p className="temp">Temprature: {weatherData.main.temp} &deg;C</p>
</div>

</div>
)

export default CardExampleCard;


weather.js

@import url('https://fonts.googleapis.com/css2?family=Recursive&display=swap');

.main{
width: 700px;
border-radius: 15px;
background-color: #01579b;
}

.header{
background-color: #424242;
color: whitesmoke;
padding: 10px;
font-size: 28px;
border-radius: 15px;
font-family: 'Recursive', sans-serif;
}

.day{
padding: 15px;
color: whitesmoke;
font-family: 'Recursive', sans-serif;
font-size: 24px;
font-weight: 600;
}

.temp{
padding: 15px;
color: whitesmoke;
font-family: 'Recursive', sans-serif;
font-size: 18px;
}
styles.css

This is how our app looks now.

Let's use flexbox to arrange the data column-wise.


<div className="flex">
<p className="day">Day: {moment().format('dddd')}</p>
</div>
<div className="flex">
<p className="temp">Temprature: {weatherData.main.temp} &deg;C</p>
</div>
Name the divs as 'flex' and add the following property in styles.css.
.flex{
display: flex;
justify-content: space-between;
}
Our weather.js will now look something like this.

import React from 'react';


import './styles.css';
import moment from 'moment';

const CardExampleCard = ({weatherData}) => (


<div className="main">
<p className="header">{weatherData.name}</p>
<div className="flex">
<p className="day">Day: {moment().format('dddd')}</p>
<p className="day">{moment().format('LL')}</p>
</div>

<div className="flex">
<p className="temp">Temprature: {weatherData.main.temp} &deg;C</p>
<p className="temp">Humidity: {weatherData.main.humidity} %</p>
</div>

</div>
)

14. Create a TODO application in react with necessary components and deploy it into github.

Registering the todo Application


Now that you have completed the setup for the backend, you can begin
registering the todo application as an installed app so that Django
can recognize it.
Open the backend/settings.py file in your code editor and
add todo to the INSTALLED_APPS:
backend/settings.py
# Application definition

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'todo',
]
Copy
Then, save your changes.
Defining the Todo Model
Let’s create a model to define how the Todo items should be stored
in the database.
Open the todo/models.py file in your code editor and add the
following lines of code:
todo/models.py
from django.db import models

# Create your models here.

class Todo(models.Model):
title = models.CharField(max_length=120)
description = models.TextField()
completed = models.BooleanField(default=False)

def _str_(self):
return self.title
Copy
The code snippet above describes three properties on the Todo model:
 title
 description
 completed
The completed property is the status of a task. A task will either
be completed or not completed at any time. Because you have created
a Todo model, you will need to create a migration file:
1. python manage.py makemigrations todo
2.
Copy
And apply the changes to the database:
1. python manage.py migrate todo
2.
Copy
You can test to see that CRUD operations work on the Todo model you
created by using the admin interface that Django provides by
default.
Open the todo/admin.py file with your code editor and add the
following lines of code:
todo/admin.py
from django.contrib import admin
from .models import Todo

class TodoAdmin(admin.ModelAdmin):
list_display = ('title', 'description', 'completed')

# Register your models here.

admin.site.register(Todo, TodoAdmin)
Copy
Then, save your changes.
You will need to create a “superuser” account to access the admin
interface. Run the following command in your terminal:
1. python manage.py createsuperuser
2.
Copy
You will be prompted to enter a username, email, and password for
the superuser. Be sure to enter details that you can remember
because you will need them to log in to the admin dashboard.
Start the server once again:
1. python manage.py runserver
2.
Copy
Navigate to http://localhost:8000/admin in your web browser. And log
in with the username and password that was created earlier:

You can create, edit, and, delete Todo items using this interface:

After experimenting with this interface, you can stop the server
(CONTROL+C or CTRL+C).
Step 2 — Setting Up the APIs
In this section, you will create an API using the Django REST
framework.
Install the djangorestframework and django-cors-headers using
Pipenv:
1. pipenv install djangorestframework django-cors-headers
2.
Copy
You need to add rest_framework and corsheaders to the list of
installed applications. Open the backend/settings.py file in your
code editor and update the INSTALLED_APPS and MIDDLEWARE sections:
backend/settings.py
# Application definition

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'corsheaders',
'rest_framework',
'todo',
]

MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'corsheaders.middleware.CorsMiddleware',
]
Copy
Then, add these lines of code to the bottom of
the backend/settings.py file:
backend/settings.py
CORS_ORIGIN_WHITELIST = [
'http://localhost:3000'
]
Copy
django-cors-headers is a Python library that will prevent the errors
that you would normally get due to CORS rules. In
the CORS_ORIGIN_WHITELIST code, you
whitelisted localhost:3000 because you want the frontend (which will
be served on that port) of the application to interact with the API.
Creating serializers
You will need serializers to convert model instances to JSON so that
the frontend can work with the received data.
Create a todo/serializers.py file with your code editor. Open
the serializers.py file and update it with the following lines of
code:
todo/serializers.py
from rest_framework import serializers
from .models import Todo

class TodoSerializer(serializers.ModelSerializer):
class Meta:
model = Todo
fields = ('id', 'title', 'description', 'completed')
Copy
This code specifies the model to work with and the fields to be
converted to JSON.
Creating the View
You will need to create a TodoView class in the todo/views.py file.
Open the todo/views.py file with your code editor and add the
following lines of code:
todo/views.py
from django.shortcuts import render
from rest_framework import viewsets
from .serializers import TodoSerializer
from .models import Todo

# Create your views here.

class TodoView(viewsets.ModelViewSet):
serializer_class = TodoSerializer
queryset = Todo.objects.all()
Copy
The viewsets base class provides the implementation for CRUD
operations by default. This code specifies the serializer_class and
the queryset.
Open the backend/urls.py file with your code editor and replace the
contents with the following lines of code:
backend/urls.py
from django.contrib import admin
from django.urls import path, include
from rest_framework import routers
from todo import views

router = routers.DefaultRouter()
router.register(r'todos', views.TodoView, 'todo')

urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include(router.urls)),
]
Copy
This code specifies the URL path for the API. This was the final
step that completes the building of the API.
You can now perform CRUD operations on the Todo model. The router
class allows you to make the following queries:
 /todos/ - returns a list of all
the Todo items. CREATE and READ operations can be performed
here.
 /todos/id - returns a single Todo item using the id primary
key. UPDATE and DELETE operations can be performed here.
Let’s restart the server:
1. python manage.py runserver
2.
Copy
Navigate to http://localhost:8000/api/todos in your web browser:

You can CREATE a new Todo item using the interface:

If the Todo item is created successfully, you will be presented with


a successful response:
You can also perform DELETE and UPDATE operations on
specific Todo items using the id primary keys. Use the address
structure /api/todos/{id} and provide an id.
Add 1 to the URL to examine the Todo item with the id of “1”.
Navigate to http://localhost:8000/api/todos/1 in your web browser:

This completes the building of the backend of the application.


Step 3 — Setting Up the Frontend
Now that you have the backend of the application complete, you can
create the frontend and have it communicate with the backend over
the interface that you created.
First, open a new terminal window and navigate to the django-todo-
react project directory.
To set up the frontend, this tutorial will rely upon Create React
App. There are several approaches to using create-react-app. One
approach is to use npx to run the package and create the project:
1. npx create-react-app frontend
2.
Copy
You can learn more about this approach by reading the How To Set Up
a React Project with Create React App.
After the project is created, you can change into the newly
created frontend directory:
1. cd frontend
2.
Copy
Then, start the application:
1. npm start
2.
Copy
Your web browser will open http://localhost:3000 and you will be
presented with the default Create React App screen:

Next, install bootstrap and reactstrap to provide user interface


tools.
1. npm install [email protected] [email protected] --legacy-peer-deps
2.
Copy
Note: You may encounter unable to resolve dependency tree errors
depending on your versions of React, Bootstrap, and Reactstrap.
At the time of the revision, the latest version of popper.js has
been deprecated and will conflict with React 17+. This is a known
issue and it is possible to use the --legacy-peer-deps option when
installing.
Open index.js in your code editor and add bootstrap.min.css:
frontend/src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import 'bootstrap/dist/css/bootstrap.css';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);

// If you want to start measuring performance in your app, pass a


function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-
vitals
reportWebVitals();
Copy
If you are having difficulty with this step, you can consult the
official documentation for adding bootstrap.
Open App.js in your code editor and add the following lines of code:
frontend/src/App.js
import React, { Component } from "react";

const todoItems = [
{
id: 1,
title: "Go to Market",
description: "Buy ingredients to prepare dinner",
completed: true,
},
{
id: 2,
title: "Study",
description: "Read Algebra and History textbook for the upcoming
test",
completed: false,
},
{
id: 3,
title: "Sammy's books",
description: "Go to library to return Sammy's books",
completed: true,
},
{
id: 4,
title: "Article",
description: "Write article on how to use Django with React",
completed: false,
},
];

class App extends Component {


constructor(props) {
super(props);
this.state = {
viewCompleted: false,
todoList: todoItems,
};
}

displayCompleted = (status) => {


if (status) {
return this.setState({ viewCompleted: true });
}

return this.setState({ viewCompleted: false });


};

renderTabList = () => {
return (
<div className="nav nav-tabs">
<span
className={this.state.viewCompleted ? "nav-link active" :
"nav-link"}
onClick={() => this.displayCompleted(true)}
>
Complete
</span>
<span
className={this.state.viewCompleted ? "nav-link" : "nav-
link active"}
onClick={() => this.displayCompleted(false)}
>
Incomplete
</span>
</div>
);
};

renderItems = () => {
const { viewCompleted } = this.state;
const newItems = this.state.todoList.filter(
(item) => item.completed == viewCompleted
);

return newItems.map((item) => (


<li
key={item.id}
className="list-group-item d-flex justify-content-between
align-items-center"
>
<span
className={`todo-title mr-2 ${
this.state.viewCompleted ? "completed-todo" : ""
}`}
title={item.description}
>
{item.title}
</span>
<span>
<button
className="btn btn-secondary mr-2"
>
Edit
</button>
<button
className="btn btn-danger"
>
Delete
</button>
</span>
</li>
));
};
render() {
return (
<main className="container">
<h1 className="text-white text-uppercase text-center my-
4">Todo app</h1>
<div className="row">
<div className="col-md-6 col-sm-10 mx-auto p-0">
<div className="card p-3">
<div className="mb-4">
<button
className="btn btn-primary"
>
Add task
</button>
</div>
{this.renderTabList()}
<ul className="list-group list-group-flush border-top-
0">
{this.renderItems()}
</ul>
</div>
</div>
</div>
</main>
);
}
}

export default App;


Copy
This code includes some hardcoded values for four items. These will
be temporary values until items are fetched from the backend.
The renderTabList() function renders two spans that help control
which set of items are displayed. Clicking on the Completed tab will
display the completed tasks. Clicking on the Incomplete tab will
display the incomplete tasks.
Save your changes and observe the application in your web browser:

To handle actions such as adding and editing tasks, you will need to
create a modal component.
First, create a components folder in the src directory:
1. mkdir src/components
2.
Copy
Then, create a Modal.js file and open it with your code editor. Add
the following lines of code:
frontend/src/components/Modal.js
import React, { Component } from "react";
import {
Button,
Modal,
ModalHeader,
ModalBody,
ModalFooter,
Form,
FormGroup,
Input,
Label,
} from "reactstrap";

export default class CustomModal extends Component {


constructor(props) {
super(props);
this.state = {
activeItem: this.props.activeItem,
};
}

handleChange = (e) => {


let { name, value } = e.target;

if (e.target.type === "checkbox") {


value = e.target.checked;
}

const activeItem = { ...this.state.activeItem, [name]: value };

this.setState({ activeItem });


};

render() {
const { toggle, onSave } = this.props;

return (
<Modal isOpen={true} toggle={toggle}>
<ModalHeader toggle={toggle}>Todo Item</ModalHeader>
<ModalBody>
<Form>
<FormGroup>
<Label for="todo-title">Title</Label>
<Input
type="text"
id="todo-title"
name="title"
value={this.state.activeItem.title}
onChange={this.handleChange}
placeholder="Enter Todo Title"
/>
</FormGroup>
<FormGroup>
<Label for="todo-description">Description</Label>
<Input
type="text"
id="todo-description"
name="description"
value={this.state.activeItem.description}
onChange={this.handleChange}
placeholder="Enter Todo description"
/>
</FormGroup>
<FormGroup check>
<Label check>
<Input
type="checkbox"
name="completed"
checked={this.state.activeItem.completed}
onChange={this.handleChange}
/>
Completed
</Label>
</FormGroup>
</Form>
</ModalBody>
<ModalFooter>
<Button
color="success"
onClick={() => onSave(this.state.activeItem)}
>
Save
</Button>
</ModalFooter>
</Modal>
);
}
}
Copy
This code creates a CustomModal class and it nests the Modal
component that is derived from the reactstrap library.
This code also defined three fields in the form:
 title
 description
 completed
These are the same fields that we defined as properties on the Todo
model in the backend.
The CustomModal receives activeItem, toggle, and onSave as props:
1. activeItem represents the Todo item to be edited.
2. toggle is a function used to control the Modal’s state (i.e.,
open or close the modal).
3. onSave is a function that is called to save the edited values
of the Todo item.
Next, you will import the CustomModal component into
the App.js file.
Revisit the src/App.js file with your code editor and replace the
entire contents with the following lines of code:
frontend/src/App.js
import React, { Component } from "react";
import Modal from "./components/Modal";

const todoItems = [
{
id: 1,
title: "Go to Market",
description: "Buy ingredients to prepare dinner",
completed: true,
},
{
id: 2,
title: "Study",
description: "Read Algebra and History textbook for the upcoming
test",
completed: false,
},
{
id: 3,
title: "Sammy's books",
description: "Go to library to return Sammy's books",
completed: true,
},
{
id: 4,
title: "Article",
description: "Write article on how to use Django with React",
completed: false,
},
];

class App extends Component {


constructor(props) {
super(props);
this.state = {
viewCompleted: false,
todoList: todoItems,
modal: false,
activeItem: {
title: "",
description: "",
completed: false,
},
};
}

toggle = () => {
this.setState({ modal: !this.state.modal });
};

handleSubmit = (item) => {


this.toggle();

alert("save" + JSON.stringify(item));
};

handleDelete = (item) => {


alert("delete" + JSON.stringify(item));
};

createItem = () => {
const item = { title: "", description: "", completed: false };

this.setState({ activeItem: item, modal: !this.state.modal });


};

editItem = (item) => {


this.setState({ activeItem: item, modal: !this.state.modal });
};

displayCompleted = (status) => {


if (status) {
return this.setState({ viewCompleted: true });
}

return this.setState({ viewCompleted: false });


};

renderTabList = () => {
return (
<div className="nav nav-tabs">
<span
className={this.state.viewCompleted ? "nav-link active" :
"nav-link"}
onClick={() => this.displayCompleted(true)}
>
Complete
</span>
<span
className={this.state.viewCompleted ? "nav-link" : "nav-
link active"}
onClick={() => this.displayCompleted(false)}
>
Incomplete
</span>
</div>
);
};

renderItems = () => {
const { viewCompleted } = this.state;
const newItems = this.state.todoList.filter(
(item) => item.completed === viewCompleted
);

return newItems.map((item) => (


<li
key={item.id}
className="list-group-item d-flex justify-content-between
align-items-center"
>
<span
className={`todo-title mr-2 ${
this.state.viewCompleted ? "completed-todo" : ""
}`}
title={item.description}
>
{item.title}
</span>
<span>
<button
className="btn btn-secondary mr-2"
onClick={() => this.editItem(item)}
>
Edit
</button>
<button
className="btn btn-danger"
onClick={() => this.handleDelete(item)}
>
Delete
</button>
</span>
</li>
));
};

render() {
return (
<main className="container">
<h1 className="text-white text-uppercase text-center my-
4">Todo app</h1>
<div className="row">
<div className="col-md-6 col-sm-10 mx-auto p-0">
<div className="card p-3">
<div className="mb-4">
<button
className="btn btn-primary"
onClick={this.createItem}
>
Add task
</button>
</div>
{this.renderTabList()}
<ul className="list-group list-group-flush border-top-
0">
{this.renderItems()}
</ul>
</div>
</div>
</div>
{this.state.modal ? (
<Modal
activeItem={this.state.activeItem}
toggle={this.toggle}
onSave={this.handleSubmit}
/>
) : null}
</main>
);
}
}

export default App;


Copy
Save your changes and observe the application in your web browser:

If you attempt to edit and save a Todo item, you will get an alert
displaying the Todo item’s object. Clicking on Save or Delete will
perform the respective actions on the Todo item.
Note:: Depending on your version of React and Reactstrap, you may
experience console errors. At the time of the revision, Warning:
Legacy context API has been detected within a strict-mode
tree. and Warning: findDOMNode is deprecated in
StrictMode. are known issues.
Now, you will modify the application so that it interacts with the
Django API you built in the previous section. Revisit the first
terminal window and ensure the server is running. If it is not
running, use the following command:
1. python manage.py runserver
2.
Copy
Note: If you closed this terminal window, remember that you will
need to navigate to the backend directory and use the virtual Pipenv
shell.
To make requests to the API endpoints on the backend server, you
will install a JavaScript library called axios.
In the second terminal window, ensure that you are in
the frontend directory and install axios:
1. npm install [email protected]
2.
Copy
Then open the frontend/package.json file in your code editor and add
a proxy:
frontend/package.json
[...]
"name": "frontend",
"version": "0.1.0",
"private": true,
"proxy": "http://localhost:8000",
"dependencies": {
"axios": "^0.18.0",
"bootstrap": "^4.1.3",
"react": "^16.5.2",
"react-dom": "^16.5.2",
"react-scripts": "2.0.5",
"reactstrap": "^6.5.0"
},
[...]
The proxy will help in tunneling API requests
to http://localhost:8000 where the Django application will handle
them. Without this proxy, you would need to specify full paths:
axios.get("http://localhost:8000/api/todos/")
Copy
With proxy, you can provide relative paths:
axios.get("/api/todos/")
Copy
Note: You might need to restart the development server for the proxy
to register with the application.
Revisit the frontend/src/App.js file and open it with your code
editor. In this step, you will remove the hardcoded todoItems and
use data from requests to the backend
server. handleSubmit and handleDelete
Open the App.js file and replace it with this final version:
frontend/src/App.js
import React, { Component } from "react";
import Modal from "./components/Modal";
import axios from "axios";

class App extends Component {


constructor(props) {
super(props);
this.state = {
viewCompleted: false,
todoList: [],
modal: false,
activeItem: {
title: "",
description: "",
completed: false,
},
};
}

componentDidMount() {
this.refreshList();
}

refreshList = () => {
axios
.get("/api/todos/")
.then((res) => this.setState({ todoList: res.data }))
.catch((err) => console.log(err));
};

toggle = () => {
this.setState({ modal: !this.state.modal });
};

handleSubmit = (item) => {


this.toggle();

if (item.id) {
axios
.put(`/api/todos/${item.id}/`, item)
.then((res) => this.refreshList());
return;
}
axios
.post("/api/todos/", item)
.then((res) => this.refreshList());
};

handleDelete = (item) => {


axios
.delete(`/api/todos/${item.id}/`)
.then((res) => this.refreshList());
};

createItem = () => {
const item = { title: "", description: "", completed: false };

this.setState({ activeItem: item, modal: !this.state.modal });


};

editItem = (item) => {


this.setState({ activeItem: item, modal: !this.state.modal });
};

displayCompleted = (status) => {


if (status) {
return this.setState({ viewCompleted: true });
}

return this.setState({ viewCompleted: false });


};

renderTabList = () => {
return (
<div className="nav nav-tabs">
<span
onClick={() => this.displayCompleted(true)}
className={this.state.viewCompleted ? "nav-link active" :
"nav-link"}
>
Complete
</span>
<span
onClick={() => this.displayCompleted(false)}
className={this.state.viewCompleted ? "nav-link" : "nav-
link active"}
>
Incomplete
</span>
</div>
);
};

renderItems = () => {
const { viewCompleted } = this.state;
const newItems = this.state.todoList.filter(
(item) => item.completed === viewCompleted
);

return newItems.map((item) => (


<li
key={item.id}
className="list-group-item d-flex justify-content-between
align-items-center"
>
<span
className={`todo-title mr-2 ${
this.state.viewCompleted ? "completed-todo" : ""
}`}
title={item.description}
>
{item.title}
</span>
<span>
<button
className="btn btn-secondary mr-2"
onClick={() => this.editItem(item)}
>
Edit
</button>
<button
className="btn btn-danger"
onClick={() => this.handleDelete(item)}
>
Delete
</button>
</span>
</li>
));
};

render() {
return (
<main className="container">
<h1 className="text-white text-uppercase text-center my-
4">Todo app</h1>
<div className="row">
<div className="col-md-6 col-sm-10 mx-auto p-0">
<div className="card p-3">
<div className="mb-4">
<button
className="btn btn-primary"
onClick={this.createItem}
>
Add task
</button>
</div>
{this.renderTabList()}
<ul className="list-group list-group-flush border-top-
0">
{this.renderItems()}
</ul>
</div>
</div>
</div>
{this.state.modal ? (
<Modal
activeItem={this.state.activeItem}
toggle={this.toggle}
onSave={this.handleSubmit}
/>
) : null}
</main>
);
}
}
export default App;
Copy
The refreshList() function is reusable that is called each time an
API request is completed. It updates the Todo list to display the
most recent list of added items.
The handleSubmit() function takes care of both the create and update
operations. If the item passed as the parameter doesn’t have an id,
then it has probably not been created, so the function creates it.
At this point, verify that your backend server is running in your
first terminal window:
1. python manage.py runserver
2.
Copy
Note: If you closed this terminal window, remember that you will
need to navigate to the backend directory and use the virtual Pipenv
shell.
And in your second terminal window, ensure that you are in
the frontend directory and start your frontend application:
1. npm start
2.
Copy
Now when you visit http://localhost:3000 with your web browser, your
application will allow you to READ, CREATE, UPDATE,
and DELETE tasks.

You might also like