DEV Community

Cover image for How to Send Data From React to Flask
Ondiek Elijah
Ondiek Elijah

Posted on • Updated on

How to Send Data From React to Flask

In our previous article on connecting a React frontend to a Flask backend, we saw how to fetch data from Flask API and then displaying it on the browser, in this continuation article we'll explore how to send data to a Flask backend from React, then update the UI with the new data.

Check my GitHub for the complete codes used in this guide.

Part 1

Configuring the Flask backend.

1. routes.py

Before we continue. Let's alter our Flask routes.py to accept input from the React frontend, then commit the database. We'll add the following lines of code to our routes.py file.

@app.route("/add", methods=["POST"], strict_slashes=False)
def add_articles():
    title = request.json['title']
    body = request.json['body']

    article = Articles(
        title=title,
        body=body
        )

    db.session.add(article)
    db.session.commit()

    return article_schema.jsonify(article)
Enter fullscreen mode Exit fullscreen mode

The function above basically gets an article title and description in json format, adds the record to the database, and then commits, i.e. saves.

Part 2

Configuring the React frontend.

In contrast to the last tutorial, we will make some changes to our project by introducing a Components directory. Then we'll add some new files, one to manage our API services and another to display a form to the UI, as well as to handle our interaction with the APIService, which provides our data to Flask.

2. Components/APIService.js

export default class APIService{
    // Insert an article
    static InsertArticle(body){
        return fetch(`http://localhost:5000/add`,{
            'method':'POST',
             headers : {
            'Content-Type':'application/json'
      },
      body:JSON.stringify(body)
    })
    .then(response => response.json())
    .catch(error => console.log(error))
    }

}
Enter fullscreen mode Exit fullscreen mode

To better organize our files and increase efficiency, we conduct all of the Flask API services in a single file and then call the methods as needed.

The code above requests our Flask routes, which handle data insertion, and then posts our JSON-stringified article title and description. Flask takes care of the rest under the hood.

3. Components/Form.js

import { useState } from 'react';
import APIService from '../Components/APIService'
Enter fullscreen mode Exit fullscreen mode

Because we'll require the React useState hook and the APIService component, we make them available as seen above.

const Form = (props) => {
    const [title, setTitle] = useState('')
    const [body, setBody] = useState('')

    const insertArticle = () =>{
      APIService.InsertArticle({title,body})
      .then((response) => props.insertedArticle(response))
      .catch(error => console.log('error',error))
    }

    const handleSubmit=(event)=>{ 
      event.preventDefault()
      insertArticle()
      setTitle('')
      setBody('')
    }

  return (
       <div>
       // Form
       </div>
  )}

export default Form;
Enter fullscreen mode Exit fullscreen mode

In the above functional component we just created, we do define two sets of variables, the title and the article body, both are subjected to the useState hook that returns the current states(title and body) and a function that updates them (setTitle and setBody).

We then invoke the APIService.InsertArticle() method.This call takes our article object - from the form submitted by the user, as an argument. The response is then sent as a parameter to a function insertedArticle that we are yet to create in the later steps inside App.js.

A Parameter is variable in the declaration of function while an argument is the actual value of this variable that gets passed to function.- Stackoverflow

In the handleSubmit function, we call insertArticle and then clear the form fields after submission.

The return statement of the Form component delivers our actual HTML form, as illustrated below.

        <form onSubmit = {handleSubmit} >

          <label htmlFor="title" className="form-label">Title</label>
          <input 
          type="text"
          className="form-control" 
          placeholder ="Enter title"
          value={title}
          onChange={(e)=>setTitle(e.target.value)}
          required
          />

          <label htmlFor="body" className="form-label">Body</label>
          <textarea 
          className="form-control" 
          placeholder ="Enter body" 
          rows='6'
          value={body}
          onChange={(e)=>setBody(e.target.value)}
          required
          >
          </textarea>

          <button 
          className="btn btn-primary mt-2"
          >
          Publish article</button>

        </form>
Enter fullscreen mode Exit fullscreen mode

3. App.js

As we near completion, we need to show the Form component on the UI. We'll import it then display it on the UI as shown in the steps below.

// import the component
import Form from './Components/Form'
Enter fullscreen mode Exit fullscreen mode

Previously, we passed the response from our APIService. InsertArticle() as a parameter, it's then received on this end. Using the spread operator we will combine the newly created article with the available articles. The update is initiated using the setArticles method and the result is a list of updated articles.

  // update the existing article list
  const insertedArticle = (article) =>{
    const new_articles = [...articles,article]
    setArticles(new_articles)
  }
Enter fullscreen mode Exit fullscreen mode

We now have our form ready to display on the UI. We can make it visible by calling the Form Component while passing to it the the data as props like this.

      <Form insertedArticle={insertedArticle} />
Enter fullscreen mode Exit fullscreen mode

Also, keeping the form visible all the time isn't ideal, so we made it a toggle button.

  // define variables for the present state of the form and another to change its state
  const [showForm, setShowForm] = useState(false);
  ...
 // toggle between the two states,visible and hidden
  const toggleShowForm = () => {
    setShowForm(!showForm);
  }
  ...
// Trigger the hide/show method
  <button 
  onClick={toggleShowForm}
  className="btn btn-primary"
  >
  Write an article
  <i className="bi bi-pencil-square m-2"></i>
  </button>
  ...
 // display the form conditionally
  {showForm && (
  <Form 
  insertedArticle={insertedArticle}
  />
  )}
Enter fullscreen mode Exit fullscreen mode

Project preview
Project preview

Thank you for reading. Please like, share, and leave a comment below.

Also do follow my blog to get notified when the next article on editing and deleting the articles we just published is posted.

Inspired by Parwiz Forogh

Follow me on Twitter

dev_elie

Top comments (6)

Collapse
 
vokabul8 profile image
Vokabul8!

I have a webapp that has a process where data is to be sorted at the back end and updated on the front end periodically (That is, data is collected from users for 6 minutes, sorted and a selection is made after meeting certain conditions, then the selection is displayed on the UI for two minutes, making a total of an 8 minute cycle). This process is to be repeated continuously infinitely.

The issue here now is that my dev says this cannot be done due to the expectation that millions of data may have to be filtered and the system cannot do it within the time frame expected?

Any ideas?

Collapse
 
johnyepthomi profile image
JohnYepthomi

You need to know exactly how long the sorting and selection process will take , making sure it gets done withing the 6mins before displaying to the user. Since I don't know what kind of sorting and selection criteria is involved , I can't help much but as you mentioned about your devs saying it can't be done , I'm guessing it involves a lot of work and the time it takes for the whole process isn't guaranteed to be consistent with the 6 mins requirement.

Collapse
 
vokabul8 profile image
Vokabul8!

Its a question and answer application in which the users have 6 minutes to submit their answers. so the sorting and selection has to be done within this 6 minutes. The criteria is a form of elimination process where the system is to compare answers sent in and select the one among all the answers sent in within the 6 minutes which meets certain conditions, to be displayed, for two minutes.

Collapse
 
ondiek profile image
Ondiek Elijah

Since what you're implementing will be stressful in production, I would recommend that you implement some indexing techniques to speed up the entire process.

Collapse
 
vokabul8 profile image
Vokabul8!

Will this "indexing technique" make the process to function as required?

Thread Thread
 
ondiek profile image
Ondiek Elijah

Certainly, yeah.