article

Tuesday, May 30, 2023

React JS Python Flask REST API CRUD (Create, Read, Update and Delete) | Axios Mysql

React JS Python Flask REST API CRUD (Create, Read, Update and Delete) | Axios Mysql

Python Flask 

https://flask.palletsprojects.com/en/2.3.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

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, request
from flask_marshmallow import Marshmallow #ModuleNotFoundError: No module named 'flask_marshmallow' = pip install flask-marshmallow https://pypi.org/project/flask-
from flask_cors import CORS, cross_origin #ModuleNotFoundError: No module named 'flask_cors' = pip install Flask-Cors
from models import db, Users

app = Flask(__name__)

app.config['SECRET_KEY'] = 'cairocoders-ednalan'
#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'

SQLALCHEMY_TRACK_MODIFICATIONS = False
SQLALCHEMY_ECHO = True
 
CORS(app, supports_credentials=True)

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

ma=Marshmallow(app)

class UserSchema(ma.Schema):
    class Meta:
        fields = ('id','name','email','password')
 
user_schema = UserSchema()
users_schema = UserSchema(many=True)
 
@app.route("/")
def hello_world():
    return "<p>Hello, World!</p>"

@app.route('/users', methods=['GET']) 
def listusers():
    all_users = Users.query.all()
    results = users_schema.dump(all_users)
    return jsonify(results)
 
@app.route('/userdetails/<id>',methods =['GET'])
def userdetails(id):
    user = Users.query.get(id)
    return user_schema.jsonify(user)
 
@app.route('/userupdate/<id>',methods = ['PUT'])
def userupdate(id):
    user = Users.query.get(id)
 
    name = request.json['name']
    email = request.json['email']
 
    user.name = name
    user.email = email
 
    db.session.commit()
    return user_schema.jsonify(user)

@app.route('/userdelete/<id>',methods=['DELETE'])
def userdelete(id):
    user = Users.query.get(id)
    db.session.delete(user)
    db.session.commit()
    return user_schema.jsonify(user)
 
@app.route('/newuser',methods=['POST'])
def newuser():
    name = request.json['name']
    email = request.json['email']
    password = request.json['password']
 
    print(name)
    print(email)
    print(password)

    users = Users(name=name, email=email, password=password)

    db.session.add(users)
    db.session.commit()
    return user_schema.jsonify(users)

if __name__ == "__main__":
    app.run(debug=True)
C:\flask_dev\flaskreact\models.py
#C:\flask_dev\flaskreact\models.py
from flask_sqlalchemy import SQLAlchemy
        
db = SQLAlchemy()
        
class Users(db.Model):
    __tablename__ = "tblusers"
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(150), index=True, unique=True)
    email = db.Column(db.String(150), index=True, unique=True)
    password = db.Column(db.String(255), index=True, unique=True)
run (venv) C:\flask_dev\flaskreact>flask run

get all user
http://127.0.0.1:5000/users

get info
http://127.0.0.1:5000/userdetails/1

put update data
http://127.0.0.1:5000/userupdate/1

delete data
http://127.0.0.1:5000/userdelete/1

post add new
http://127.0.0.1:5000/newuser

json
{
"name":"cairocoders ednalan",
"email":"cairocoders@gmail.com",
"password":"123456"
}

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

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

Run
C:\react-js\myreactdev> npm start

C:\react-js\myreactdev\src\App.js

//C:\react-js\myreactdev\src\App.js
import React, {  } from "react";
import "./App.css";

import Home from "./components/Home";
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import View from "./components/View";
import Edit from "./components/Edit";

function App() {
  return (
    <div className="App">
        <Router>
            <Routes>
              <Route exact path="/" element={<Home/>}/>
              <Route exact path="/view/:id" element={<View/>}/>
              <Route exact path="/edit/:id" element={<Edit/>}/> 
            </Routes>
        </Router>
	</div>
  );
}

export default App;
https://github.com/axios/axios

Installing the Axios Client

$ npm install axios
C:\reactdev\myreactdev>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:\react-js\myreactdev\src\components\Home.js
//C:\react-js\myreactdev\src\components\Home.js
import React, { useState } from 'react';
import List from './List';
import axios from 'axios';

const Home = () => {

    const [userField, setUserField] = useState({
        name: "",
        email: "",
        password: ""
    });

    const changeUserFieldHandler = (e) => {
        setUserField({
            ...userField,
            [e.target.name]: e.target.value
        });
        //console.log(userField);

    }
    const [loading,setLoading]=useState()

    const onSubmitChange = async (e) => {
        e.preventDefault();
        try {
            const responce= await axios.post("http://127.0.0.1:5000/newuser", userField);
			console.log(responce)
            setLoading(true);
        } catch (err) {
            console.log("Something Wrong");
        }
    }
    if(loading){
        return <Home/>
    }

    return (
        <div className="container">
            <h2 className='w-100 d-flex justify-content-center p-3'>React JS Laravel 10 REST API CRUD (Create, Read, Update and Delete) | Axios Mysql</h2>
                <div className='row'>
                    <div className='col-md-4'>
                        <h3>Add Your Detail</h3>
                        <form>
                            <div className="mb-3 mt-3">
                                <label className="form-label"> Full Name:</label>
                                <input type="text" className="form-control" id="name" placeholder="Enter Your Full Name" name="name" onChange={e => changeUserFieldHandler(e)} />
                            </div>
                            <div className="mb-3 mt-3">
                                <label className="form-label">Email:</label>
                                <input type="email" className="form-control" id="email" placeholder="Enter email" name="email" onChange={e => changeUserFieldHandler(e)} required/>
                            </div>
                            <div className="mb-3 mt-3">
                                <label className="form-label">Password:</label>
                                <input type="text" className="form-control" id="password" placeholder="Enter password" name="password" onChange={e => changeUserFieldHandler(e)} required/>
                            </div>
							
                            <button type="submit" className="btn btn-primary" onClick={e => onSubmitChange(e)}>Add User</button>
                        </form>
                    </div>
                    <div className='col-md-8'>
                        <List />
                    </div>
                </div>
        </div>
    )
};

export default Home;
C:\react-js\myreactdev\src\components\List.js
//C:\react-js\myreactdev\src\components\List.js
import React, { useState, useEffect } from 'react';
import { NavLink } from 'react-router-dom';
import axios from 'axios'


const List = () => {
    const [userData, setUSerData] = useState([]);
    useEffect(() => {
        fetchData();
    }, [])

    const fetchData = async () => {
        try {
            const result = await axios("http://127.0.0.1:5000/users");
            //console.log(result.data);
            setUSerData(result.data)
        } catch (err) {
            console.log("somthing Wrong");
        }
    }

    const handleDelete=async(id)=>{
		console.log(id);
        await axios.delete("http://127.0.0.1:5000/userdelete/"+id);
        const newUserData=userData.filter((item)=>{
            return(
                item.id !==id
            )
        })
        setUSerData(newUserData);
    }

    return(
		<div className="container">
        <h3>User Details</h3>
        <table className="table table-bordered">
            <thead>
                <tr>
                    <th>S No.</th>
                    <th>Full Name</th>
                    <th>Email</th>
                    <th>Actions</th>
                </tr>
            </thead>
            <tbody>
                {
                    userData.map((user, i) => {
                        return (
                            <tr key={i}>
                                <td>{i + 1}</td>
                                <td>{user.name} </td>
                                <td>{user.email} </td>
                                <td>
									<NavLink to={`/view/${user.id}`} className="btn btn-success mx-2">View</NavLink>
									<NavLink to={`/edit/${user.id}`} className="btn btn-info mx-2">Edit</NavLink>
									<button onClick={()=>handleDelete(user.id)} className="btn btn-danger">Delete</button>
								</td>
                            </tr>
                        )
                    })
                }

            </tbody>
        </table>
		</div>
	);
};

export default List;
C:\react-js\myreactdev\src\components\View.js
//C:\react-js\myreactdev\src\components\View.js
import axios from 'axios';
import React, { useState, useEffect } from 'react';
import { useParams,useNavigate } from 'react-router-dom';

const View = () => {
    const {id}=useParams();
    // console.log(id);
    const[user,setUser]=useState([]);
	const navigate = useNavigate();

    useEffect(()=>{
        fetchUser();
    },[id]);

    const fetchUser=async()=>{
        try{
        const result=await axios.get("http://127.0.0.1:5000/userdetails/"+id);
        console.log(result.data);
        setUser(result.data)

        }catch(err){
            console.log("Something Wrong");
        }
    }

    const clickToBackHandler=()=>{
		navigate('/');
    }

    return <div>
        <div className="container">
            <div className='row'>
                <div className='col-md-12'>

                    <h1>User Details</h1>
                    <table className="table">
                        <thead>
                            <tr>
                                <th>S No.</th>
                                <th>Full Name</th>
                                <th>Email</th>
                              
                            </tr>
                        </thead>
                        <tbody>
                            <tr>
                                <td>{user.id}</td>
                                <td>{user.name}</td>
                                <td>{user.email}</td>
                            </tr>

                        </tbody>
                    </table>
                </div>

            </div>
        </div>
        <div className='container d-flex justify-content-center'>
            <div><button className='btn btn-primary' onClick={clickToBackHandler}>Back To Home</button></div>
        </div>
    </div>;
};

export default View;
C:\react-js\myreactdev\src\components\Edit.js
//C:\react-js\myreactdev\src\components\Edit.js
import React,{ useState, useEffect } from 'react';
import axios from 'axios';
import { useNavigate ,useParams } from 'react-router-dom';

const Edit = () => {
    const {id}=useParams()
	const navigate = useNavigate();
    const clickToBackHandler=()=>{
		navigate('/');
    }

    const [userField, setUserField] = useState({
        name: "",
        email: ""
    });

    useEffect(()=>{
        fetchUser();
    },[id])

    const fetchUser=async()=>{
        try{
			const result=await axios.get("http://127.0.0.1:5000/userdetails/"+id);
			// console.log(result.data);
			setUserField(result.data)
        }catch(err){
            console.log("Something Wrong");
        }
    }

    const changeUserFieldHandler = (e) => {
        setUserField({
            ...userField,
            [e.target.name]: e.target.value
        });
        console.log(userField);
    }
    
    const onSubmitChange = async (e) => {
        e.preventDefault();
        try {
            await axios.put("http://127.0.0.1:5000/userupdate/"+id, userField);
			navigate('/');	
        } catch (err) {
            console.log("Something Wrong");
        }
    }

    return(
		<div className="container">
			<h1>Edit Form</h1>
			<form>
				<div className="mb-3 mt-3">
					<label className="form-label"> ID:</label>
					<input type="text" className="form-control" id="id" name="id" value={id} disabled />
				</div>
				<div className="mb-3 mt-3">
					<label className="form-label"> Full Name:</label>
					<input type="text" className="form-control" placeholder="Enter Your Full Name" name="name" value={userField.name} onChange={e => changeUserFieldHandler(e)} />
				</div>
				<div className="mb-3 mt-3">
					<label className="form-label">Email:</label>
					<input type="email" className="form-control" id="email" placeholder="Enter email" name="email" value={userField.email}  onChange={e => changeUserFieldHandler(e)}/>
				</div>
                <div className="mb-3 mt-3">
                     <label className="form-label">Password:</label>
                      <input type="text" className="form-control" id="password" placeholder="Enter password" name="password" onChange={e => changeUserFieldHandler(e)} required/>
                </div>
				<button type="submit" className="btn btn-primary" onClick={e=>onSubmitChange(e)}>Update</button>
			</form>
			<div className='container d-flex justify-content-center'>
				<button className='btn btn-primary' onClick={ clickToBackHandler}>Back To Home</button>
			</div>
		</div>
	);
};

export default Edit;
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