Home > Back-end >  Flask app: Post json to server for use in a different REST API
Flask app: Post json to server for use in a different REST API

Time:10-20

I have a Flask app with some vanilla Javascript (I don't know JQuery). It does the following: (1) The user enters some data in an HTML table. (2) The data is then parsed to JSON. (3) I want to post the JSON file to the server. (4) From the server, the JSON object is posted to a different REST API for further use.

Steps 1, 2 and 4 work (I can console.log the JSON object), but I'm at a loss how to post a JSON object from client to server. The option I keep seeing is to move the table between tags and then post the table via request.form. I'm happy to do that but it seems clunky compared to parsing JSON on the client side and posting a clean object to the server that can be used immediately by the third-party REST API. What am I missing here?

<!DOCTYPE html>
    <html>
    <body>
    <body>
      <button id="click">Click</button>
      <table id="myTable">
<thead>
  <tr>
    <th>ID</th>
    <th>Name</th>
    <th>Price</th>
  </tr>
</thead>
<tbody>
  <tr>
    <td>001</td>
    <td>Trousers</td>
    <td>9.99</td>
  </tr>
  <tr>
    <td>002</td>
    <td>Shirt</td>
    <td>19.99</td>
  </tr>
  <tr>
    <td>003</td>
    <td>Shoes</td>
    <td>49.99</td>
  </tr>
</tbody>
</table>


    </body>

    <script>
      const btn = document.getElementById("click");
      btn.addEventListener("click", function () {
        tableToJson(table);
      })
      
    let table = document.getElementById("myTable");
    function tableToJson(table) {
    var data = [];

    // first row needs to be headers
    var headers = [];
    for (var i=0; i<table.rows[0].cells.length; i  ) {
        headers[i] = table.rows[0].cells[i].innerHTML.toLowerCase().replace(/ /gi,'');
    }

    // go through cells
    for (var i=1; i<table.rows.length; i  ) {

        var tableRow = table.rows[i];
        var rowData = {};

        for (var j=0; j<tableRow.cells.length; j  ) {

            rowData[ headers[j] ] = tableRow.cells[j].innerHTML;

        }

        data.push(rowData);
    }       
    console.log(data);
    
    return data;
}
    </script>
    </html>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

app = Flask(__name__) # Create an Instance

@app.route('/', methods=['GET', 'POST']) # Route the Function and allow Requests
def main(): # Run the function
    if request.method == 'POST': # Identify Request Method
        value = request.form['input'] # Gather the Post Request
        return value
    if request.method == 'GET': # Identify Request Method
        return render_template('index.html')

app.run(host='0.0.0.0', port=5000, debug=True) # Run the Application (in debug mode)```

CodePudding user response:

Use the Fetch API to send the data.
In the following example, the data is converted into a JSON-compliant character string and sent to the server via POST.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>
    <button id="click">Click</button>
    <table id="my-table">
      <thead>
        <tr>
          <th>ID</th>
          <th>Name</th>
          <th>Price</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>001</td>
          <td>Trousers</td>
          <td>9.99</td>
        </tr>
        <tr>
          <td>002</td>
          <td>Shirt</td>
          <td>19.99</td>
        </tr>
        <tr>
          <td>003</td>
          <td>Shoes</td>
          <td>49.99</td>
        </tr>
      </tbody>
    </table>

    <script type="text/javascript">
      (() => {
        const tableToJSON = (tableElem) => {
          const tableRows = Array.from(tableElem.rows);
          const tableHead = Array.from(tableRows[0].cells).map(cell => {
            return cell.innerHTML.toLowerCase().replace(/ /g,'_')
          });
          return tableRows.slice(1).map(row => {
            const rowData = {}
            Array.from(row.cells).forEach((cell, i) => {
              return rowData[tableHead[i]] = cell.innerHTML;
            });
            return rowData;
          });
        };

        const btnElem = document.getElementById('click');
        btnElem.addEventListener('click', (evt) => {
          const tableElem = document.getElementById('my-table');
          const tableData = tableToJSON(tableElem);

          // Post JSON data to the server.
          const url = '/data';
          fetch(url, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify(tableData)
          }).then(resp => resp.json())
            .then(data => console.log(data));
        });
      })();
    </script>
  </body>
</html>

Then you can request and process the data on the server using request.get_json(). The response from the server is a simple JSON object that was converted with jsonify.

from flask import Flask
from flask import render_template, request, jsonify

app = Flask(__name__)
app.secret_key = 'your secret here'

@app.route('/', methods=['GET'])
def index():
    return render_template('index.html')

@app.route('/data', methods=['POST']) 
def data(): 
    data = request.get_json()
    print(data)
    return jsonify(success=True)
  • Related