Download Laravel App
composer create-project --prefer-dist laravel/laravel my-app
C:\xampp\htdocs\laravel10project>composer create-project laravel/laravel laravel10project
Connecting our Database
open .env file root directory.
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laraveldb
DB_USERNAME=root
DB_PASSWORD=
Create Model and Migration
C:\xampp\htdocs\laravel\laravelproject>php artisan make:model Product -m
A new file named Product.php will be created in the app directory and database/migrations directory to generate the table in our database
app/Models/Product.php
//app/Models/Product.php <?php namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Product extends Model { use HasFactory; protected $fillable = [ 'name', 'image', 'description' ]; }database\migrations\create_products_table.php
//database\migrations\create_products_table.php <?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; return new class extends Migration { public function up(): void { Schema::create('products', function (Blueprint $table) { $table->id(); $table->string('name'); $table->string('image'); $table->text('description'); $table->timestamps(); }); } public function down(): void { Schema::dropIfExists('products'); } };Database Migration
php artisan migrate
C:\xampp\htdocs\laravel\laravel10project>php artisan migrate
Migration table created successfully.
check database table
Create Controller and Request
C:\xampp\htdocs\laravel\laravel10project>php artisan make:controller ProductController -r
app\Http\Controllers\ProductController.php
//app\Http\Controllers\ProductController.php <?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Models\Product; use App\Http\Requests\ProductStoreRequest; use Illuminate\Support\Str; use Illuminate\Support\Facades\Storage; //php artisan storage:link = php artisan storage:link = http://127.0.0.1:8000/storage/1.jpg class ProductController extends Controller { public function index() { // All Product $products = Product::all(); // Return Json Response return response()->json([ 'products' => $products ],200); } public function store(ProductStoreRequest $request) { try { $imageName = Str::random(32).".".$request->image->getClientOriginalExtension(); // Create Product Product::create([ 'name' => $request->name, 'image' => $imageName, 'description' => $request->description ]); // Save Image in Storage folder Storage::disk('public')->put($imageName, file_get_contents($request->image)); // Return Json Response return response()->json([ 'message' => "Product successfully created." ],200); } catch (\Exception $e) { // Return Json Response return response()->json([ 'message' => "Something went really wrong!" ],500); } } public function show($id) { // Product Detail $product = Product::find($id); if(!$product){ return response()->json([ 'message'=>'Product Not Found.' ],404); } // Return Json Response return response()->json([ 'product' => $product ],200); } public function update(ProductStoreRequest $request, $id) { try { // Find product $product = Product::find($id); if(!$product){ return response()->json([ 'message'=>'Product Not Found.' ],404); } //echo "request : $request->image"; $product->name = $request->name; $product->description = $request->description; if($request->image) { // Public storage $storage = Storage::disk('public'); // Old iamge delete if($storage->exists($product->image)) $storage->delete($product->image); // Image name $imageName = Str::random(32).".".$request->image->getClientOriginalExtension(); $product->image = $imageName; // Image save in public folder $storage->put($imageName, file_get_contents($request->image)); } // Update Product $product->save(); // Return Json Response return response()->json([ 'message' => "Product successfully updated." ],200); } catch (\Exception $e) { // Return Json Response return response()->json([ 'message' => "Something went really wrong!" ],500); } } public function destroy($id) { // Detail $product = Product::find($id); if(!$product){ return response()->json([ 'message'=>'Product Not Found.' ],404); } // Public storage $storage = Storage::disk('public'); // Iamge delete if($storage->exists($product->image)) $storage->delete($product->image); // Delete Product $product->delete(); // Return Json Response return response()->json([ 'message' => "Product successfully deleted." ],200); } }Next, create a Request
C:\xampp\htdocs\laravel\laravel10project>php artisan make:request ProductStoreRequest
app\Http\Requests\ProductStoreRequest.php
//app\Http\Requests\ProductStoreRequest.php <?php namespace App\Http\Requests; use Illuminate\Foundation\Http\FormRequest; class ProductStoreRequest extends FormRequest { /** * Determine if the user is authorized to make this request. */ public function authorize(): bool { //return false; return true; } /** * Get the validation rules that apply to the request. * * @return array<string, \Illuminate\Contracts\Validation\Rule|array|string> */ public function rules(): array { if(request()->isMethod('post')) { return [ 'name' => 'required|string|max:258', 'image' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048', 'description' => 'required|string' ]; } else { return [ 'name' => 'required|string|max:258', 'image' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg|max:2048', 'description' => 'required|string' ]; } } public function messages() { if(request()->isMethod('post')) { return [ 'name.required' => 'Name is required!', 'image.required' => 'Image is required!', 'description.required' => 'Descritpion is required!' ]; } else { return [ 'name.required' => 'Name is required!', 'description.required' => 'Descritpion is required!' ]; } } }Routes
All API requests will need the header Accept: application/json.
open routes/api.php and update the following code
routes\api.php
//routes\api.php <?php use Illuminate\Http\Request; use Illuminate\Support\Facades\Route; use App\Http\Controllers\ProductController; Route::middleware('auth:sanctum')->get('/user', function (Request $request) { return $request->user(); }); Route::get('products', [ProductController::class, 'index']); Route::get('products/{id}', [ProductController::class, 'show']); Route::post('products', [ProductController::class, 'store']); Route::put('productsupdate/{id}', [ProductController::class, 'update']); Route::delete('productdelete/{id}', [ProductController::class, 'destroy']);generate symbolic links C:\xampp\htdocs\laravel\laravel10project>php artisan storage:link
Run C:\xampp\htdocs\laravel\laravel10project>php artisan serve
Starting Laravel development server: http://127.0.0.1:8000
open postman new request
GET api/products Index All products return.
GET : http://127.0.0.1:8000/api/products
GET api/products/{id} Show Detail of a particular post by ID.
GET : http://127.0.0.1:8000/api/products/1
POST api/products Store Create a new product.
POST : http://127.0.0.1:8000/api/products
body
key value
name Iphone 13
image iphone.jpg = file
description product description
PUT api/products/{id} Update Update a particular product by ID.
POST : http://127.0.0.1:8000/api/products/1
body
key value
_method PUT
name Iphone 13 updated
image iphone.jpg = file
description product description updated
DELETE api/products/{id} Destroy Delete a particular product by ID.
DELETE : http://127.0.0.1:8000/api/products/1
React JS
https://create-react-app.dev/
Create Project
C:\react-js>npx create-react-app myreactdev
Run
C:\react-js\myreactdev> npm start
https://github.com/axios/axios
Installing the Axios Client
$ npm install axios
Install React Router Dom
https://www.npmjs.com/package/react-router-dom
C:\react-js\myreactdev>npm i react-router-dom --save
C:\reactdev\myreactdev>npm install axios
C:\react-js\myreactdev\src\App.js
//C:\react-js\myreactdev\src\App.js import React, { } from "react"; import "./App.css"; import { BrowserRouter as Router, Route, Routes } from 'react-router-dom'; import Header from './Component/Header'; import Home from './Component/Home'; import Addproduct from './Component/Addproduct'; import Productlist from './Component/Productlist'; import EditProduct from './Component/EditProduct'; import Footer from './Component/Footer'; function App() { return ( <div className="App"> <Router> <Header/> <Routes> <Route exact path="/" element={<Home/>}/> <Route exact path="/addproduct" element={<Addproduct/>}/> <Route exact path="/productlist" element={<Productlist/>}/> <Route path="editproduct/:id/edit" element={<EditProduct />} /> </Routes> <Footer/> </Router> </div> ); } export default App;C:\react-js\myreactdev\src\Component\Header.js
//C:\react-js\myreactdev\src\Component\Header.js import React, { } from "react"; import {NavLink} from 'react-router-dom'; function Header() { return( <React.Fragment> <nav className="navbar navbar-expand-lg bg-primary" > <div className="container"> <NavLink to="/" className="navbar-brand">Cairocoders</NavLink> <button className="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> <span className="navbar-toggler-icon"></span> </button> <div className="collapse navbar-collapse" id="navbarSupportedContent"> <ul className="navbar-nav me-auto mb-2 mb-lg-0"> <li className="nav-item"> <NavLink to="/" className="nav-link" aria-current="page">Home</NavLink> </li> <li className="nav-item"> <NavLink to="/productlist" className="nav-link"> Product List</NavLink> </li> <li className="nav-item"> <NavLink to="/addproduct" className="nav-link">Add Product</NavLink> </li> </ul> </div> </div> </nav> </React.Fragment> ); } export default Header;C:\react-js\myreactdev\src\Component\Home.js
//C:\react-js\myreactdev\src\Component\Home.js import React, { } from "react"; function Home() { return( <React.Fragment> <div className="container"> <div className="row"> <div className="col-md-12"> <h1>React Laravel 10 REST API Crud (Create, Read, Update and Delete) with Upload image</h1> </div> </div> </div> </React.Fragment> ); } export default Home;C:\react-js\myreactdev\src\Component\Footer.js
//C:\react-js\myreactdev\src\Component\Footer.js import React, { } from "react"; function Footer() { return( <React.Fragment> <footer className="bg-primary fixed-bottom"> <div className="container"> <div className="row"> <div className="col-md-12 mt-3"> <p>Copyright @2023 Cairocoders</p> </div> </div> </div> </footer> </React.Fragment> ); } export default Footer;C:\react-js\myreactdev\src\Component\Addproduct.js
//C:\react-js\myreactdev\src\Component\Addproduct.js import React, { useState } from "react"; import axios from "axios"; import { useNavigate } from "react-router-dom"; function Addproduct() { const navigate = useNavigate(); const[txtname, setName]= useState(''); const[txtdescription, setdescription]= useState(''); const[fileimage, setPhoto]= useState(''); const[message, setMessage]= useState(''); const uploadProduct= async()=>{ console.log(fileimage) const formData= new FormData(); formData.append('name', txtname); formData.append('description',txtdescription); formData.append('image', fileimage); const responce= await axios.post("http://127.0.0.1:8000/api/products", formData, { headers:{'Content-Type':"multipart/form-data"}, } ); if(responce) { console.log(responce) setMessage(responce.message); //"message": "Product successfully created." setTimeout(()=>{ navigate('/productlist'); }, 2000); } } const handleSubmit= async(e)=>{ e.preventDefault(); await uploadProduct(); } return( <React.Fragment> <div className="container"> <div className="row"> <div className="col-md-8 mt-4"> <h5 className="mb-4">Add Product </h5> <p className="text-warning">{ message}</p> <form onSubmit={ handleSubmit}> <div className="mb-3 row"> <label className="col-sm-3">Product Title </label> <div className="col-sm-9"> <input type="text" className="form-control" onChange={ (e)=>setName(e.target.value)}/> </div> </div> <div className="mb-3 row"> <label className="col-sm-3">Description </label> <div className="col-sm-9"> <input type="text" className="form-control" onChange={(e)=>setdescription(e.target.value)} /> </div> </div> <div className="mb-3 row"> <label className="col-sm-3">Product Image</label> <div className="col-sm-9"> <input type="file" className="form-control" onChange={(e)=>setPhoto(e.target.files[0])} /> </div> </div> <div className="mb-3 row"> <label className="col-sm-3"></label> <div className="col-sm-9"> <button type="submit" className="btn btn-success">Submit</button> </div> </div> </form> </div> </div> </div> </React.Fragment> ); } export default Addproduct;C:\react-js\myreactdev\src\Component\Productlist.js
//C:\react-js\myreactdev\src\Component\Productlist.js import React, { useState, useEffect } from "react"; import { Link } from "react-router-dom"; import axios from "axios"; function Productlist() { const[product, setProduct]= useState([]); useEffect( ()=>{ const getProduct= ()=>{ fetch("http://127.0.0.1:8000/api/products") .then(res=>{ return res.json()}) .then(response=>{ console.log(response.products) setProduct(response.products) }) .catch(error=>{ console.log(error)}); } getProduct(); },[]); const deleteProduct = (id) => { axios.delete('http://127.0.0.1:8000/api/productdelete/'+id).then(function(response){ console.log(response.data); alert("Successfully Deleted"); }); } return( <React.Fragment> <div className="container container_overflow"> <div className="row"> <div className="col-12"> <h5 className="mb-4">Product List</h5> <p className="text-danger"> </p> <table className="table table-bordered"> <thead> <tr> <th scope="col">Sr.No</th> <th scope="col">Product Title</th> <th scope="col">Product Description</th> <th scope="col">Product Image</th> <th scope="col" width="200">Action</th> </tr> </thead> <tbody> { product.map((pdata, index)=>( <tr key={index}> <td>{index+1 } </td> <td>{pdata.name } </td> <td>{pdata.description } </td> <td><img src={`http://127.0.0.1:8000/storage/${pdata.image}`} alt="" height={50} width={90} /></td> <td> <Link to={`/editproduct/${pdata.id}/edit`} className="btn btn-success mx-2">Edit</Link> <button onClick={() => deleteProduct(pdata.id)} className="btn btn-danger">Delete</button> </td> </tr> )) } </tbody> </table> </div> </div> </div> </React.Fragment> ); } export default Productlist;C:\react-js\myreactdev\src\Component\EditProduct.js
//C:\react-js\myreactdev\src\Component\EditProduct.js import React, { useState, useEffect } from "react"; import axios from "axios"; import { useParams, useNavigate } from "react-router-dom"; function EditProduct() { const navigate = useNavigate(); const {id}= useParams(); const[message, setMessage]= useState(''); const [inputs, setInputs] = useState([]); const [fileimage, setPhoto]= useState(''); const handleChange = (event) => { const name = event.target.name; const value = event.target.value; setInputs(values => ({...values, [name]: value})); } const uploadProduct= async()=>{ const formData= new FormData(); formData.append('_method', 'PUT'); formData.append('name', inputs.name); formData.append('description',inputs.description); formData.append('image', fileimage); const response= await axios.post("http://127.0.0.1:8000/api/productsupdate/"+id, formData, { headers:{'Content-Type':"multipart/form-data"}, } ); setMessage(response.data.message); //"message": "Product successfully updated.." console.log(response) setTimeout(()=>{ navigate('/productlist'); }, 2000); } const handleSubmit= async(e)=>{ e.preventDefault(); await uploadProduct(); } useEffect(() => { getproduct(); }, []); function getproduct() { axios.get('http://127.0.0.1:8000/api/products/'+id).then(function(response) { console.log(response); setInputs(response.data.product); }); } return( <React.Fragment> <div className="container"> <div className="row"> <div className="col-md-8 mt-4"> <h5 className="mb-4">Edit Product </h5> <p className="text-success"><b>{ message }</b></p> <form onSubmit={ handleSubmit}> <div className="mb-3 row"> <label className="col-sm-3">Product Title </label> <div className="col-sm-9"> <input type="text" value={inputs.name} className="form-control" name="name" onChange={ handleChange}/> </div> </div> <div className="mb-3 row"> <label className="col-sm-3">Description </label> <div className="col-sm-9"> <input type="text" value={inputs.description} className="form-control" name="description" onChange={ handleChange} /> </div> </div> <div className="mb-3 row"> <label className="col-sm-3">Product Image</label> <div className="col-sm-9"> <img src={`http://127.0.0.1:8000/storage/${inputs.image}`} alt="" height={300} width={300} /> <input type="file" className="form-control" onChange={(e)=>setPhoto(e.target.files[0])} /> </div> </div> <div className="mb-3 row"> <label className="col-sm-3"></label> <div className="col-sm-9"> <button type="submit" className="btn btn-success">Submit</button> </div> </div> </form> </div> </div> </div> </React.Fragment> ); } export default EditProduct;react-js\myreactdev\src\App.css
//react-js\myreactdev\src\App.css body{ background:#eee; } .nav-link { color:#ffffff; } .navbar-brand{ color:#ffffff; } .fixed-bottom{ color:#ffffff; }react-js\myreactdev\public\index.html
//react-js\myreactdev\public\index.html <!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="manifest" href="%PUBLIC_URL%/manifest.json" /> <title>React App</title> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"/> </head> <body> <noscript>You need to enable JavaScript to run this app.</noscript> <div id="root"></div> </body> </html>Run C:\react-j\myreactdev>npm start
http://localhost:3000/