article

Monday, April 24, 2023

ReactJS Python Flask Pagination using react-paginate

ReactJS Python Flask Pagination using react-paginate

Python Flask 

https://flask.palletsprojects.com/en/2.2.x/installation/
 
Create an environment
C:\flask_dev>py -3 -m venv venv

Activate the environment
C:\flask_dev>venv\Scripts\activate

Install Flask
venv C:\flask_dev>pip install Flask
C:\flask_dev\flaskreact\app.py

Install requirements

Flask-SQLAlchemy
Flask-SQLAlchemy is an extension for Flask that adds support for SQLAlchemy to your application.
https://flask-sqlalchemy.palletsprojects.com/en/3.0.x/

(venv) PS C:\flask_dev\flaskreact>pip install -U Flask-SQLAlchemy
C:\flask_dev\flaskreact\app.py

Flask + marshmallow for beautiful APIs
https://pypi.org/project/flask-marshmallow/

(venv) PS C:\flask_dev\flaskreact>pip install flask-marshmallow

Flask-Cors
A Flask extension for handling Cross Origin Resource Sharing (CORS), making cross-origin AJAX possible.
https://pypi.org/project/Flask-Cors/

(venv) PS C:\flask_dev\flaskreact>pip install -U flask-cors

C:\flask_dev\flaskreact\app.py
//C:\flask_dev\flaskreact\app.py
from flask import Flask, jsonify
from flask_cors import CORS #ModuleNotFoundError: No module named 'flask_cors' = pip install Flask-Cors
from flask_marshmallow import Marshmallow #ModuleNotFoundError: No module named 'flask_marshmallow' = pip install flask-marshmallow https://pypi.org/project/flask-marshmallow/

from models import db, Countries

app = Flask(__name__)
CORS(app, supports_credentials=True)

#app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///flaskdb.db'
# Databse configuration mysql                             Username:password@hostname/databasename
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:''@localhost/flaskreact'

db.init_app(app)
  
with app.app_context():
    db.create_all()

ma=Marshmallow(app)
 
class CountriesSchema(ma.Schema):
    class Meta:
        fields = ('ID','countryName')
         
countries_schema = CountriesSchema(many=True)

@app.route("/")
def hello_world():
    return "Hello, World!" 

@app.route('/posts/<int:page>/<int:per_page>', methods=['GET'])
def posts(page=1, per_page=10):

    total = Countries.query.count()
    print(total)

    posts = Countries.query.order_by(Countries.ID.asc())  
    posts = posts.paginate(page=page, per_page=per_page)

    return jsonify({
        'total': total,
        'page': page,
        'per_page': per_page,
        'has_next': posts.has_next,
        'has_prev': posts.has_prev,
        'page_list': [iter_page if iter_page else '...' for iter_page in posts.iter_pages()],
        'posts': [{
            'id': p.ID,
            'title': p.countryName,
        } for p in posts.items]
    })
C:\flask_dev\flaskreact\models.py
 
#C:\flask_dev\flaskreact\models.py
from flask_sqlalchemy import SQLAlchemy
   
db = SQLAlchemy()
   
class Countries(db.Model):
    __tablename__ = "countries"
    ID = db.Column(db.Integer, primary_key=True)
    countryName = db.Column(db.String(120), index=True, unique=True)
run (venv) C:\flask_dev\flaskreact>flask run
http://127.0.0.1:5000/posts/1/10

React JS
https://create-react-app.dev/

Create Project
C:\react-js>npx create-react-app myreactdev

Install react-paginate
react-paginate A ReactJS component to render a pagination.
C:\react-js>npm install react-paginate --save

Run
C:\react-js\myreactdev> npm start
C:\react-js\myreactdev\src\App.js
//C:\react-js\myreactdev\src\App.js
import React, { useEffect, useState } from 'react';
import "./App.css";
import ReactPaginate from "react-paginate"; //npm install react-paginate --save = https://www.npmjs.com/package/react-paginate

function App() {

  const [items, setItems] = useState([]);

  const [pageCount, setpageCount] = useState(0);

  let limit = 10;

  useEffect(() => {
    const getPost = async () => {
      const res = await fetch(
         `http://127.0.0.1:5000/posts/1/${limit}`
      );
      const data = await res.json();
      //console.log(data.posts);
      const totalrec = data.total
      const total = totalrec;
      console.log(total);
      setpageCount(Math.ceil(total / limit));
      // console.log(Math.ceil(total/12));
      setItems(data.posts);
    };
 
    getPost();
  }, [limit]);

  const fetchPost = async (currentPage) => {
    const res = await fetch(
       `http://127.0.0.1:5000/posts/${currentPage}/${limit}`
    );
    const data = await res.json();
    return data.posts;
  };

  const handlePageClick = async (data) => {
    console.log(data.selected);
 
    let currentPage = data.selected + 1;
 
    const listpage = await fetchPost(currentPage);

    setItems(listpage);
  };

  return (
    <div className="container">
    <div className="container" style={{padding: 20}}>
      <h4 className="d-inline-block">ReactJS Python Flask Pagination using react-paginate</h4>
    </div>

      <table className="table table-striped">
          <thead className="thead-light ">
            <th>ID</th>
            <th>Country</th>
          </thead>
          <tbody>
          {items.map(row => <tr>
            <td>{row.id}</td>
              <td>{row.title}</td>
            </tr>)}
          </tbody>
        </table>

        <ReactPaginate
            previousLabel={"previous"}
            nextLabel={"next"}
            breakLabel={"..."}
            pageCount={pageCount}
            marginPagesDisplayed={2}
            pageRangeDisplayed={3}
            onPageChange={handlePageClick}
            containerClassName={"pagination justify-content-center"}
            pageClassName={"page-item"}
            pageLinkClassName={"page-link"}
            previousClassName={"page-item"}
            previousLinkClassName={"page-link"}
            nextClassName={"page-item"}
            nextLinkClassName={"page-link"}
            breakClassName={"page-item"}
            breakLinkClassName={"page-link"}
            activeClassName={"active"}
        />
    </div>
  );
}
 
export default App;
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/

Related Post