Building a web application using React and asp.net core(Part 02)

6 minute read

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.

Download Source Code