React CRUD Example with CodeIgniter

We will see Codeigniter REST + ReactJS CRUD example. We have seen previously Codeigniter REST API examples for GET, POST, PUT and DELETE, but we will see them together. We will use ReactJS as a front-end technology to represent our UI. We can make any CRUD Operation in Codeigniter.

In this React CRUD example with CodeIgniter 4 and MySQL, I am using React JS for the front-end. CodeIgniter framework for the REST (Representational State Transfer) APIs and MySQL database will be used as persistent storage. You can use MongoDB either Sqllite for the database.

Download the PROJECT From here : Source Code ( Google Drive )

Read more tutorials on React JS : Captcha Validation in ReactJS

Our React Project Images

Some More Images

Watch Video Tutorial

Our Coding part Starts here

Before proceeding ,Download these Packages for Reacts JS Project

– npm install axios – npm install bootstrap – npm install concurrently – npm install react-router-dom

Now We paste this code inside App.js file

App.js

import React from "react";
import "./App.css";
import "../node_modules/bootstrap/dist/css/bootstrap.css";
import Home from "./components/products/Home";
import Navbar from "./components/layout/Navbar";
import { BrowserRouter as Router, Route,Switch,withRouter} from "react-router-dom";
import AddProduct from "./components/products/AddProduct";
import EditProduct from "./components/products/EditProduct";
function App(props) {
  return (
    <Router>
      <div className="App">
        <Navbar />
        <Switch>
          <Route exact path="/" component={Home} />
          <Route exact path="/products/add" component={AddProduct} />
          <Route exact path="/products/edit/:id" component={EditProduct} />
        </Switch>
      </div>
    </Router>
  );
}
export default App;

Then create folder ( components / layouts / Home.js ) . Home.js will display your data

Home.js

import React, { useState, useEffect } from "react";
import axios from "axios";
import { Link } from "react-router-dom";

const Home = () => {
  const [users, setUser] = useState([]);

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

  const loadUsers = async () => {
    const result = await axios.get("http://localhost/ci_cart_geek/show_product");
    setUser(result.data.reverse());
  };

  const deleteUser = (productId) =>
  {
    axios.delete('http://localhost/ci_cart_geek/delete-product/delete/'+productId)
    .then((result)=>{
      loadUsers();
    })
    .catch(()=>{
      alert('Error in the Code');
    });
  };

  return (
    <div className="container">
      <div className="py-4">
        <h3 class="mb-3 text-center">Product Details</h3>
        <table class="table border shadow">
          <thead class="thead-primary">
            <tr>
              <th scope="col">Serial No</th>
              <th scope="col">Product Name</th>
              <th scope="col">Product Price</th>
              <th scope="col">Product Description</th>
              <th>Action</th>
            </tr>
          </thead>
          <tbody>
            {users.map((user, index) => (
              <tr>
                <th scope="row">{index + 1}</th>
                <td>{user.product_name}</td>
                <td>{user.product_price}</td>
                <td>{user.product_description}</td>
                <td>
                 <Link class=" mr-2" to={`/products/edit/${user.id}`}>
                     <i class="fa fa-edit" aria-hidden="true"></i> 
                  </Link>
                  <Link class="" onClick={() => deleteUser(user.id)}>
                  <i class="fa fa-trash" aria-hidden="true"></i> 
                  </Link>
                </td>
              </tr>
             ))}
          </tbody>
        </table>
      </div>
    </div>
  );
};

export default Home;

Now We will create Add page means Insert data into database .( src/components / layouts / AddProduct.js ).

AddProduct.js

import React, { useState } from "react";
import axios from 'axios'

//import { useHistory } from "react-router-dom";

const AddProduct = () => {
  // let history = useHistory(); // Use for Navigate on Previous
  const [user, setUser] = useState({
    product_name: "",
    product_price: "",
    product_description: ""
  });

  const { product_name, product_price, product_description} = user;
  
  const onInputChange = e => {
    setUser({ ...user, [e.target.name]: e.target.value });
  };
  
  const onSubmit = async e => {
    e.preventDefault();
    await axios.post("http://localhost:3000/posts",user);
    alert('Data Inserted');
    // history.push("/");
  };
  return (
    <div className="container bg-light">
      <div class="row">  
       <div className="col-sm-4 mx-auto shadow p-5">
        <h2 className="text-center mb-4">Add A Product</h2>
        <form onSubmit={e => onSubmit(e)}>
          <div className="form-group">
            <input
              type="text"
              className="form-control form-control-lg"
              placeholder="Enter Product Name"
              name="product_name"
              value={product_name}
              onChange={e => onInputChange(e)}
            />
          </div>
          <div className="form-group">
            <input
              type="text"
              className="form-control form-control-lg"
              placeholder="Enter Product Price"
              name="product_price"
              value={product_price}
              onChange={e => onInputChange(e)}
            />
          </div>
          <div className="form-group">
            <input
              type="text"
              className="form-control form-control-lg"
              placeholder="Enter Product Description"
              name="product_description"
              value={product_description}
              onChange={e => onInputChange(e)}
            />
          </div>
         
          <button className="btn btn-primary btn-block">Add Product</button>
        </form>
      </div>
    </div>
  </div>  
  );
};

export default AddProduct;

Now we will create a file for Edit Update page (src/components/layouts/EditProduct.js ).

EditProduct.js

import React, { useState, useEffect } from "react";
import axios from "axios";
import { useHistory, useParams } from "react-router-dom";

const EditProduct = () => {
  
  let history = useHistory(); //The useHistory hook gives you access to the history instance that you may use to navigate.
  const { id } = useParams();  //The useParams() hook helps us to access the URL parameters from a current route. 
  const [user, setUser] = useState({
    product_name: "",
    product_price: "",
    product_description: ""
  });

  const { product_name, product_price, product_description } = user;
  const onInputChange = e => {
    setUser({ ...user, [e.target.name]: e.target.value });
  };

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

  const onSubmit = async e => {
    e.preventDefault();
    await axios.put(`http://localhost/ci_cart_geek/update-product/update/${id}`, user);
    history.push("/");
  };

  const loadUser = async () => {
    const result = await axios.get(`http://localhost/ci_cart_geek/get_product/${id}`);
    setUser(result.data);
  };
  return (
    <div className="container">
     <div className="row"> 
      <div className="col-sm-5 col-offset-3 mx-auto shadow p-5">
        <h2 className="text-center mb-4">Edit A Product</h2>
        <form onSubmit={e => onSubmit(e)}>
        <div className="form-group">
            <input
              type="text"
              className="form-control form-control-lg"
              placeholder="Id"
              name=""
              value={id}
              onChange={e => onInputChange(e)}
            />
          </div>
          <div className="form-group">
            <input
              type="text"
              className="form-control form-control-lg"
              placeholder="Enter Product Name"
              name="product_name"
              value={product_name}
              onChange={e => onInputChange(e)}
            />
          </div>
          <div className="form-group">
            <input
              type="text"
              className="form-control form-control-lg"
              placeholder="Enter Product Price"
              name="product_price"
              value={product_price}
              onChange={e => onInputChange(e)}
            />
          </div>
          <div className="form-group">
            <input
              type="text"
              className="form-control form-control-lg"
              placeholder="Enter Product Description"
              name="product_description"
              value={product_description}
              onChange={e => onInputChange(e)}
            />
          </div>
          <button className="btn btn-secondary btn-block">Update User</button>
        </form>
       </div>
      </div> 
    </div>
  );
};

export default EditProduct;

We also need navbar page ( Header Page ) So create one more Folder inside components folder ( src/components / layouts / Navbar.js ).

components / layouts / Navbar.js

import React from "react";
import { Link, NavLink } from "react-router-dom";
const Navbar = () => {
  return (
    <nav className="navbar navbar-expand-lg navbar-dark">
      <div className="container">
        <button
          className="navbar-toggler"
          type="button"
          data-toggle="collapse"
          data-target="#navbarSupportedContent"
          aria-controls="navbarSupportedContent"
          aria-expanded="false"
          aria-label="Toggle navigation"
        >
          <span className="navbar-toggler-icon"></span>
        </button>

        <div className="collapse navbar-collapse">
          <ul className="navbar-nav mr-auto">
            <li className="nav-item">
              <NavLink className="btn btn-outline-success" exact to="/">
                View Product
              </NavLink>
            </li>
          </ul>
          <Link className="btn btn-outline-success" to="/products/add">Add Product</Link>
        </div>
      </div>
    </nav>
  );
};

export default Navbar;

Our React part has been done. Now, will go for Backend code ( CodeIgniter PHP ). PHP Code will fetch records from the database.

First create Routing for CodeIgniter API ( application/config/routes.php)

$route['show_product'] = 'Product_detail/products';
$route['create_product'] = 'Product_detail/createProduct';
// $route['delete-product'] = 'Product_detail/deleteProduct';
$route['get_product/(:num)'] = 'Product_detail/getProduct/$1';

// $route['edit_product/(:num)'] = 'Product_detail/editProduct/$1';

$route['delete-product/delete/(:num)'] = 'Product_detail/deleteProduct/$1';

$route['edit-product/edit/(:num)']= 'Product_detail/getProduct/$1';


$route['update-product/update/(:num)']= 'Product_detail/updateProduct/$1';

Now Create a file inside controller folder of CodeIgniter . ( Must write database name in CI -> ci_react_project )

Controller/Product_detail.php

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Product_detail extends CI_Controller {

  public function __construct()
  {
    parent::__construct();
    $this->load->model('Product_action');
    $this->load->helper('url_helper');
  }
  
  public function products()
  { 
    header("Access-Control-Allow-Origin: *");
    $products = $this->Product_action->get_products();
    $this->output->set_content_type('application/json')->set_output(json_encode($products));
  
  }

  public function getProduct($id)
  { 
    
    header('Access-Control-Allow-Origin: *');
	
	echo $id;
	exit;
	
    $product = $this->Product_action->get_product($id);
	
	

    $productData = array(
      'id' => $product->id,
      'product_name' => $product->product_name,
      'product_price' => $product->product_price,
      'product_description' => $product->product_description
      // 'product_image' => $product->product_image
    );

    $this->output
      ->set_content_type('application/json')
      ->set_output(json_encode($productData));
   }

  public function createProduct()
  { 
    header("Content-type:application/json");
    header('Access-Control-Allow-Origin: *');
    header('Access-Control-Allow-Methods: POST, GET, DELETE, PUT, PATCH, OPTIONS');
    header('Access-Control-Allow-Headers: token, Content-Type');

    $requestData = json_decode(file_get_contents('php://input'), true);

    if( ! empty($requestData)) {

      $productName = $requestData['product_name'];
      $productPrice = $requestData['product_price'];
      $productDescription = $requestData['product_description'];
      // $productImage = $requestData['product_image'];
      
      $productData = array(
        'product_name' => $productName,
        'product_price' => $productPrice,
        'product_description' => $productDescription
        // 'product_image' =>$productImage
      );

      $id = $this->Product_action->insert_product($productData);

      $response = array(
        'status' => 'success',
        'message' => 'Product added successfully'
      );
    }
    else {
      $response = array(
        'status' => 'error'
      );
    }

    $this->output
      ->set_content_type('application/json')
      ->set_output(json_encode($response));
  }

  public function updateProduct($id)
  { 
    header("Content-type:application/json");
    header('Access-Control-Allow-Origin: *');
    header('Access-Control-Allow-Methods: POST, GET, DELETE, PUT, PATCH, OPTIONS');
    header('Access-Control-Allow-Headers: token, Content-Type');

    $requestData = json_decode(file_get_contents('php://input'), true);

    if(!empty($requestData)) {

      $productName = $requestData['product_name'];
      $productPrice = $requestData['product_price'];
      $productDescription = $requestData['product_description'];
      // $productImage = $requestData['product_image'];
      
      $productData = array(
        'product_name' => $productName,
        'product_price' => $productPrice,
        'product_description' => $productDescription
        // 'product_image' =>$productImage
      );

      $id = $this->Product_action->update_product($id, $productData);

      $response = array(
        'status' => 'success',
        'message' => 'Product updated successfully.'
      );
    }
    else {
      $response = array(
        'status' => 'error'
      );
    }

    $this->output
      ->set_content_type('application/json')
      ->set_output(json_encode($response));
  }

  public function deleteProduct($id)
  {
    header("Content-type:application/json");
    header('Access-Control-Allow-Origin: *');
    header('Access-Control-Allow-Methods: POST, GET, DELETE, PUT, PATCH, OPTIONS');
    header('Access-Control-Allow-Headers: token, Content-Type');
    
    $product = $this->Product_action->delete_product($id);
    $response = array(
      'message' => 'Product deleted successfully.'
    );

    $this->output
      ->set_content_type('application/json')
      ->set_output(json_encode($response));
  }
}
?>

Now try this project on your system http://localhost:3000

Read More Tutorials – >

Leave a Reply

Your email address will not be published. Required fields are marked *