How to pass data from React Form -> Flask Backend -> React Component (does it have something to do with CORS)?

13,857

Sending data to your flask back end is a POST request but you are using a GET request. So your fetch in React js should be

   fetch("/result", {
        method:"POST",
        cache: "no-cache",
        headers:{
            "content_type":"application/json",
        },
        body:JSON.stringify(this.state.value)
        }
    ).then(response => {

    return response.json()
  })
  .then(json => {

  this.setState({playerName: json[0]})
  })

Your flask method should also be a POST method

@app.route('/result', methods = ['POST'])
def result():
    player_id = request.json
    if player_id:
       data = get_player(player_id)
       name = str(data['name'][0])
       return jsonify(name)
   return "No player information is given"

You would need CORS in your flask so

pip install flask-cors then in your code

from flask_cors import CORS

app = Flask(__name__, static_folder='../frontend/build')

CORS(app)

Also you dint post your react js package so make sure you have your proxy added in your package.json like this

  "name": "client",
  "version": "0.1.0",
  "private": true,
  "proxy": "http://0.0.0.0:5000",

I assume the rest of your code works so this is just to answer your question in relation to setting up a connection between Flask and React JS.

You would be able to recieve data in flask from React but you would have a problem sending json data from the database in flask to reactjs . For the database handling I usually use Flask-SQLAlchemy and data I get from the database isnt a json object so I have to serialize the model into JSON and this achieved through a package called flask-marshmellow. So look into use those two packages

Share:
13,857

Related videos on Youtube

Tom Jackson
Author by

Tom Jackson

Updated on October 10, 2022

Comments

  • Tom Jackson
    Tom Jackson over 1 year

    Hi I am a complete React beginner and have a fairly basic question. I am looking to perform the following steps:

    (1) Provide user a form to input some text (2) Ingest the input into the Flask backend and return a new value after performing some operations (3) Provide the result from (2) to the user in front end view

    I'd like this process to be a single page app where the user does not get redirected to another page on step (3).

    Here is my App.js code:

    import React from 'react';
    import './App.css';
    
    class App extends React.Component {
    
     constructor(props) {
        super(props);
        this.state = {value: '',
                      playerName: ''};
    
        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
      }
    
      handleChange(event) {
        this.setState({value: event.target.value});
      }
    
      handleSubmit(event) {
        console.log("making request")
        fetch('/result')
          .then(response => {
            console.log(response)
            return response.json()
          })
          .then(json => {
          console.log=(json)
          this.setState({playerName: json[0]})
          })
      }
    
      render() {
        return (
          <div>
            <form onSubmit={this.handleSubmit} action="http://localhost:5000/result" method="get">
            <label>
              Player ID:
              <input type="text" name="player_id"/>
              <input type="submit" onChange={this.handleChange} value={this.state.value} />
            </label>
          </form>
            <h1> Player Name: {this.state.playerName} </h1>
          </div>
        );
      }
    }
    
    
    export default App
    
    

    Here is my main.py code:

    from flask import Flask, request, jsonify, send_from_directory
    from sqlalchemy import create_engine
    import pandas as pd
    
    app = Flask(__name__, static_folder='../frontend/build')
    
    @app.route('/result', methods = ['GET'])
    def result():
        if request.method == 'GET':
            player_id = request.args.get('player_id', None)
            if player_id:
                data = get_player(player_id)
                name = str(data['name'][0])
                return jsonify(name)
            return "No player information is given"
    
    
    def get_player(player_id):
        engine = create_engine(
            'postgres://fzmokkqt:********************-***-******-@********.com:*****/******')
        sql = """SELECT * from players WHERE id={player_id}"""
        data = pd.read_sql_query(sql.format(player_id=player_id), con=engine)
        return data
    
    @app.route('/', defaults={'path': ''})
    @app.route('/<path:path>')
    def serve(path):
        if path != "" and os.path.exists("frontend/build/" + path):
            return send_from_directory('../frontend/build', path)
        else:
            return send_from_directory('../frontend/build', 'index.html')
    
    if __name__ == '__main__':
        app.run(debug=True, host='0.0.0.0')
    

    When I run this code, I receive the intended result however it is not placed in the HTML as described in the App.js code. Instead, the result is rendered into a new page (on localhost:5000 instead of localhhost:3000 which is where the React code is rendered).