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()
{
//$products = Product::all(); // All Product
$products = Product::paginate(4);
// Return Json Response
return response()->json([
'results' => $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);
}
}
}
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::post('products', [ProductController::class, 'store']);
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
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
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
C:\reactdev\myreactdev>npm install axios
C:\react-js\myreactdev\src\App.js
//C:\react-js\myreactdev\src\App.js
import React, { useEffect, useState } from "react";
import axios from "axios";
// Component
import Navbar from "./Component/Navbar";
import ProductList from "./Component/ProductList";
function App() {
const [products, setProducts] = useState([]);
const [info, setInfo] = useState({});
const url = "http://127.0.0.1:8000/api/products";
const fetchProducts = (url) => {
axios
.get(url)
.then((data) => {
setProducts(data.data.results.data);
//console.log(data.data.results.data);
setInfo(data.data.results);
//console.log(data.data.results.next_page_url);
})
.catch((error) => {
console.log(error);
});
};
const handleNextPage = () => {
fetchProducts(info.next_page_url);
window.scrollTo(0, 0);
};
const handlePreviousPage = () => {
fetchProducts(info.prev_page_url);
window.scrollTo(0, 0);
};
useEffect(() => {
fetchProducts(url);
}, []);
return (
<>
<Navbar brand="Cairocoders" />
<div className="container py-5"><p><h2>React js Laravel 10 REST API Show Product List with pagination Next Prev</h2></p>
<nav>
<ul className="pagination justify-content-center">
{info.prev_page_url ? (
<li className="page-item">
<button className="page-link" onClick={handlePreviousPage}>
Previous
</button>
</li>
) : null}
{info.next_page_url ? (
<li className="page-item">
<button className="page-link" onClick={handleNextPage}>
Next
</button>
</li>
) : null}
</ul>
</nav>
</div>
<ProductList products={products} />
<div className="container pb-5">
<nav>
<ul className="pagination justify-content-center">
{info.prev_page_url ? (
<li className="page-item">
<button className="page-link" onClick={handlePreviousPage}>
Previous
</button>
</li>
) : null}
{info.next_page_url ? (
<li className="page-item">
<button className="page-link" onClick={handleNextPage}>
Next
</button>
</li>
) : null}
</ul>
</nav>
</div>
</>
);
}
export default App;
C:\react-js\myreactdev\src\Component\Navbar.js
//C:\react-js\myreactdev\src\Component\Navbar.js
import React from "react";
const Navbar = ({ brand }) => {
return (
<nav className="navbar navbar-dark bg-dark">
<div className="container">
<a className="navbar-brand text-uppercase" href="/">
{brand}
</a>
</div>
</nav>
);
};
export default Navbar;
C:\react-js\myreactdev\src\Component\ProductList.js
//C:\react-js\myreactdev\src\Component\ProductList.js
import React from "react";
const ProductList = ({ products }) => {
return (
<div className="container">
<div className="row">
{products.map((item, index) => (
<div key={index} className="col-lg-3 col-md-6 col-sm-12 mb-4">
<div className="card" style={{ minWidth: "200px" }}>
<img src={`http://127.0.0.1:8000/storage/${item.image}`} alt="Product list" className="card-img-top" />
<div className="card-body">
<h5 className="card-title">{item.name}</h5>
<hr />
<p className="card-text">Description: {item.description}</p>
</div>
</div>
</div>
))}
</div>
</div>
);
};
export default ProductList;
react-js\myreactdev\src\Index.css
//react-js\myreactdev\src\index.css
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
background-color: #000000;
overflow-x: hidden;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
monospace;
}
h2 {
color:#fff;
}
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/
