Building a web application using React and asp.net core(Part 02)
In the previous article, I have shown you how to create a back end application using asp.net core web api. I have created some api end points for employee profile. In this article, I will design react pages, connect with api end points and perform CRUD operation using react.
Step 1: Install axios to make http request
- Go to terminal -> go to the directory -> ClientApp
- Run the command
npm install axios --save
Step 2: Write class components
- Create a “Employee” folder in src->components.
- Now create List, Create, Delete and Edit componets in the employee folder as follows
Employee.jsx
import React, {Component} from 'react';
import axios from 'axios';
// export keyword is a new feature in ES6 let export your functions ,
// variables so you can get access to them in other js files
export class Employees extends Component
{
constructor(props){
super(props);
this.OnEmployeeEdit = this.OnEmployeeEdit.bind(this);
this.OnEmployeeDelete = this.OnEmployeeDelete.bind(this);
this.onEmployeeCreate = this.onEmployeeCreate.bind(this);
this.state = {
employees: [],
loading: true,
failed: false,
error: ''
}
}
/*Lifecycle Method: The componentDidMount() method runs after
the component output has been rendered to the DOM.*/
componentDidMount(){
this.populateEmployeesData();
}
// Event handler for create button
onEmployeeCreate()
{
const {history} = this.props;
history.push('/create');
}
// Event handler for edit button
OnEmployeeEdit(id){
const {history} = this.props;
history.push('/edit/'+id);
}
// Event handler for delete button
OnEmployeeDelete(id){
const {history} = this.props;
history.push('/delete/'+id);
}
populateEmployeesData(){
axios.get("api/Employees/GetEmployees").then(result => {
const response = result.data;
this.setState({employees: response, loading: false, error: ""});
}).catch(error => {
this.setState({employees: [], loading: false, failed: true, error: "Employess could not be loaded!"});
});
}
renderAllEmployeeTable(employees){
return(
<table className="table table-striped">
<thead>
<tr>
<th>Name</th>
<th>Designation</th>
<th>Father's Name</th>
<th>Mother's Name</th>
<th>Date of Birth</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{
employees.map(employee => (
<tr key={employee.id}>
<td>{employee.name}</td>
<td>{employee.designation}</td>
<td>{employee.fathersName}</td>
<td>{employee.mothersName}</td>
<td>{ new Date(employee.dateOfBirth).toISOString().slice(0,10)}</td>
<td><button onClick={()=> this.OnEmployeeEdit(employee.id)} className= "btn btn-success">Edit</button> ||
<button onClick={()=> this.OnEmployeeDelete(employee.id)} className= "btn btn-danger">Delete</button></td>
</tr>
))
}
</tbody>
</table>
);
}
render(){
let content = this.state.loading ? (
<p>
<em>Loading...</em>
</p>
):(
this.renderAllEmployeeTable(this.state.employees)
)
return(
<div>
<h2>Employee</h2>
<button onClick={()=> this.onEmployeeCreate()} className="btn btn-primary">Create</button>
{content}
</div>
);
}
}
Create.jsx
import React, { Component } from "react";
import axios from "axios";
export class Create extends Component{
constructor(props){
super(props);
this.onChangeName = this.onChangeName.bind(this);
this.onChangeDesignation = this.onChangeDesignation.bind(this);
this.onChangeFathersName = this.onChangeFathersName.bind(this);
this.onChangeMothersName = this.onChangeMothersName.bind(this);
this.onChangeDOB = this.onChangeDOB.bind(this);
this.onSubmit = this.onSubmit.bind(this);
this.state = {
name: '',
designation: '',
fathersName: '',
mothersName: '',
//This is date time object
dateOfBirth: null
}
}
onChangeName(e){
this.setState({
name: e.target.value
})
}
onChangeDesignation(e){
this.setState({
designation: e.target.value
})
}
onChangeFathersName(e){
this.setState({
fathersName: e.target.value
})
}
onChangeMothersName(e){
this.setState({
mothersName: e.target.value
})
}
onChangeDOB(e){
this.setState({
dateOfBirth: e.target.value
})
}
onSubmit(e){
e.preventDefault();
const {history} = this.props;
let employeeObj = {
name: this.state.name,
designation: this.state.designation,
fathersName: this.state.fathersName,
mothersName: this.state.mothersName,
dateOfBirth: this.state.dateOfBirth
}
axios.post("api/Employees/AddEmployee", employeeObj).then(result => {
history.push('/employees');
})
}
render(){
return(
<div className="row">
<div className="col-md-4">
<h3>Add new employee</h3>
<form onSubmit={this.onSubmit}>
<div className="form-group">
<label className="control-label">Name: </label>
<input className="form-control" type="text" value = {this.state.name} onChange={this.onChangeName}></input>
</div>
<div className="form-group">
<label className="control-label">Designation: </label>
<input className="form-control" type="text" value = {this.state.designation} onChange={this.onChangeDesignation}></input>
</div>
<div className="form-group">
<label className="control-label">Father's Name: </label>
<input className="form-control" type="text" value = {this.state.fathersName} onChange={this.onChangeFathersName}></input>
</div>
<div className="form-group">
<label className="control-label">Mother's Name: </label>
<input className="form-control" type="text" value = {this.state.mothersName} onChange={this.onChangeMothersName}></input>
</div>
<div className="form-group">
<label className="control-label">Date of Birth: </label>
<input className="form-control" type="date" value = {this.state.dateOfBirth} onChange={this.onChangeDOB}></input>
</div>
<div className="form-group">
<input type="submit" value = "Add Employee" className="btn btn-primary"></input>
</div>
</form>
</div>
</div>
)
}
}
_Edit.jsx
import axios from "axios";
import React, { Component } from "react";
export class Edit extends Component {
constructor(props) {
super(props);
this.onChangeName = this.onChangeName.bind(this);
this.onChangeDesignation = this.onChangeDesignation.bind(this);
this.onChangeFathersName = this.onChangeFathersName.bind(this);
this.onChangeMothersName = this.onChangeMothersName.bind(this);
this.onChangeDOB = this.onChangeDOB.bind(this);
this.onSubmit = this.onSubmit.bind(this);
this.state = {
id : '',
name: '',
designation: '',
fathersName: '',
mothersName: '',
//This is date time object
dateOfBirth: null
}
}
componentDidMount(){
const {id} = this.props.match.params;
axios.get("api/Employees/Employee/" + id).then(employee =>{
const response = employee.data;
this.setState({
id : response.id,
name: response.name,
designation: response.designation,
fathersName: response.fathersName,
mothersName: response.mothersName,
dateOfBirth: new Date(response.dateOfBirth).toISOString().slice(0,10)
})
})
//alert(id);
}
onChangeName(e) {
this.setState({
name: e.target.value
});
}
onChangeDesignation(e) {
this.setState({
designation: e.target.value
});
}
onChangeFathersName(e) {
this.setState({
fathersName: e.target.value
});
}
onChangeMothersName(e) {
this.setState({
mothersName: e.target.value
});
}
onChangeDOB(e) {
this.setState({
dateOfBirth: e.target.value
});
}
onUpdateCancel(){
const {history} = this.props;
history.push('/employees');
}
onSubmit(e){
e.preventDefault();
const {history} = this.props;
const {id} = this.props.match.params;
let employeeObj = {
id: this.state.id,
name: this.state.name,
designation: this.state.designation,
fathersName: this.state.fathersName,
mothersName: this.state.mothersName,
dateOfBirth: new Date(this.state.dateOfBirth).toISOString()
}
axios.put("api/Employees/EditEmployee/"+id, employeeObj).then(result => {
history.push('/employees');
})
}
render() {
return (
<div className="row">
<div className="col-md-4">
<h3>Edit Employee</h3>
<form onSubmit={this.onSubmit}>
<div className="form-group">
<label className="control-label">Name: </label>
<input className="form-control" type="text" value={this.state.name} onChange={this.onChangeName}></input>
</div>
<div className="form-group">
<label className="control-label">Designation: </label>
<input className="form-control" type="text" value={this.state.designation} onChange={this.onChangeDesignation}></input>
</div>
<div className="form-group">
<label className="control-label">Father's Name: </label>
<input className="form-control" type="text" value={this.state.fathersName} onChange={this.onChangeFathersName}></input>
</div>
<div className="form-group">
<label className="control-label">Mother's Name: </label>
<input className="form-control" type="text" value={this.state.mothersName} onChange={this.onChangeMothersName}></input>
</div>
<div className="form-group">
<label className="control-label">Date of Birth: </label>
<input className="form-control" type="date" value={this.state.dateOfBirth} onChange={this.onChangeDOB}></input>
</div>
<div className="form-group">
<button onClick={this.onUpdateCancel} className="btn btn-default">Cancel</button>
<input type="submit" value="Edit" className="btn btn-primary"></input>
</div>
</form>
</div>
</div>
)
}
}
Delete.jsx
import axios from "axios";
import React, { Component } from "react";
export class Delete extends Component{
constructor(props){
super(props);
this.onCancel = this.onCancel.bind(this);
this.onConfirmation = this.onConfirmation.bind(this);
this.state = {
name: '',
designation: '',
fathersName: '',
mothersName: '',
dateOfBirth: null
}
}
componentDidMount(){
const {id} = this.props.match.params;
axios.get("api/Employees/Employee/" + id).then(employee =>{
const response = employee.data;
this.setState({
id : response.id,
name: response.name,
designation: response.designation,
fathersName: response.fathersName,
mothersName: response.mothersName,
dateOfBirth: new Date(response.dateOfBirth).toISOString().slice(0,10)
})
})
}
onCancel() {
const { history } = this.props;
history.push('/employees');
}
onConfirmation(e){
e.preventDefault();
const {id} = this.props.match.params;
const {history} = this.props;
axios.delete("api/Employees/DeleteEmployee/" + id).then(result => {
history.push('/employees');
})
}
render(){
return(
<div>
<h2>Delete</h2>
<h3>Are you sure you want to delete this?</h3>
<div>
<h4>Employee</h4>
<dl class="row">
<dt class="col-sm-2">
Name:
</dt>
<dd class="col-sm-10">
{this.state.name}
</dd>
<dt class="col-sm-2">
Designation:
</dt>
<dd class="col-sm-10">
{this.state.designation}
</dd>
<dt class="col-sm-2">
Father's Name:
</dt>
<dd class="col-sm-10">
{this.state.fathersName}
</dd>
<dt class="col-sm-2">
Mother's Name:
</dt>
<dd class="col-sm-10">
{this.state.mothersName}
</dd>
<dt class="col-sm-2">
Date of Birth:
</dt>
<dd class="col-sm-10">
{this.state.dateOfBirth}
</dd>
</dl>
<form onSubmit={this.onConfirmation}>
<input type="hidden" asp-for="Id" />
<button type="submit" class="btn btn-danger">Delete</button> |
<button onClick={this.onCancel} className="btn btn-primary">Back to List</button>
</form>
</div>
</div>
)
}
}
Step 3: Add Route in App.js
- Modify App.js as follows
- Here I have define route for employees, create, edit, delete
App.js
import React, { Component } from 'react';
import { Route } from 'react-router';
import { Layout } from './components/Layout';
import { Home } from './components/Home';
import { FetchData } from './components/FetchData';
import { Counter } from './components/Counter';
import './custom.css'
import {Employees} from './components/Employee/Employees';
import { Create } from './components/Employee/Create';
import { Edit } from './components/Employee/Edit';
import { Delete } from './components/Employee/Delete';
export default class App extends Component {
static displayName = App.name;
render () {
return (
<Layout>
<Route exact path='/' component={Home} />
<Route path='/employees' component={Employees} />
<Route path='/create' component = {Create}></Route>
<Route path='/Edit/:id' component = {Edit}></Route>
<Route path='/Delete/:id' component = {Delete}></Route>
<Route path='/counter' component={Counter} />
<Route path='/fetch-data' component={FetchData} />
</Layout>
);
}
}
Step 4: Add Employee in the menu
- Add Employee link in the menu
- Change NavMenu.js as follows
NavMenu.js
import React, { Component } from 'react';
import { Collapse, Container, Navbar, NavbarBrand, NavbarToggler, NavItem, NavLink } from 'reactstrap';
import { Link } from 'react-router-dom';
import './NavMenu.css';
export class NavMenu extends Component {
static displayName = NavMenu.name;
constructor (props) {
super(props);
this.toggleNavbar = this.toggleNavbar.bind(this);
this.state = {
collapsed: true
};
}
toggleNavbar () {
this.setState({
collapsed: !this.state.collapsed
});
}
render () {
return (
<header>
<Navbar className="navbar-expand-sm navbar-toggleable-sm ng-white border-bottom box-shadow mb-3" light>
<Container>
<NavbarBrand tag={Link} to="/">HRM</NavbarBrand>
<NavbarToggler onClick={this.toggleNavbar} className="mr-2" />
<Collapse className="d-sm-inline-flex flex-sm-row-reverse" isOpen={!this.state.collapsed} navbar>
<ul className="navbar-nav flex-grow">
<NavItem>
<NavLink tag={Link} className="text-dark" to="/">Home</NavLink>
</NavItem>
<NavItem>
<NavLink tag={Link} className="text-dark" to="/employees">Employees</NavLink>
</NavItem>
<NavItem>
<NavLink tag={Link} className="text-dark" to="/counter">Counter</NavLink>
</NavItem>
<NavItem>
<NavLink tag={Link} className="text-dark" to="/fetch-data">Fetch data</NavLink>
</NavItem>
</ul>
</Collapse>
</Container>
</Navbar>
</header>
);
}
}
Step 5: Run and test the application
- Go to terminal and type
dotnet run
to run the application - Now view, insert, update and delete employee information.