Home > Blockchain >  400 error when adding second variable to Ajax data in Flask app
400 error when adding second variable to Ajax data in Flask app

Time:10-01

I am trying to use Ajax to handle forms in my Flask application.

Here is the code I have now:

Flask/Python:

@main.route('/reply/', methods=["GET", "POST"])
def reply():
    if request.method == "POST":

        reply = request.form['reply']
        reply_to_id = request.form['reply_to_id']
        

        if reply:
            now = datetime.now()
            formatted_date = now.strftime("%Y-%m-%d %X")
            reply_to_id = request.form.get("reply_to_id")
            blarg_db.replies.insert({"reply_to_id": reply_to_id, "username": current_user.username, "date": formatted_date, "reply": reply})

            return jsonify({'reply': reply})

    return redirect(url_for('main.home'))

AJAX:

$('.submit-reply').click(function(event) {

  var theReply = $(".reply-text").val()
  var replyToId = $(".reply_to_id").val()
  $.ajax({
    type : 'POST',
    url : '/reply/',
    dataType: "json",
    data : {'reply': theReply,
        'reply_to_id': replyToId},
  
    success : function(data){
      $("#reply-test").text(data['reply']);
    }
  
  })

  event.preventDefault();

});

HTML:

<form action="{{ url_for('main.reply') }}" class="reply-form" style="display: none;" method="POST">
    <textarea class="reply-text" placeholder="What's your response to that?" name="reply-text"></textarea>

    <input type="text" value={{ request.url }} style="display: none;" name="current_url">

    <input type="text" class="reply_to_id" value={{ post["_id"] }} style="display: none;" name="reply_to_id">


    <button class="submit-reply" type="submit"> Submit </button>
</form>

I keep getting a 400 Bad Request error with the code as it is, but when I remove the second variable in the data section of my AJAX code like in the following example, it works:

$('.submit-reply').click(function(event) {

  var theReply = $(".reply-text").val()
  var replyToId = $(".reply_to_id").val()
  console.log(replyToId)
  $.ajax({
    type : 'POST',
    url : '/reply/',
    dataType: "json",
    data : {'reply': theReply},
  
    success : function(data){
      $("#reply-test").text(data['reply']);
    }
  
  })

  event.preventDefault();

});

How can I add both variables to the AJAX data and avoid this error?

CodePudding user response:

I don't see why the second variable should throw an error.
Since I think you could simplify your code, I'll give you this example.

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

app = Flask(__name__)

@app.route('/')
def index():
    post = { '_id': 2021 } # example data
    return render_template('index.html', **locals())

@app.route('/reply', methods=['POST'])
def reply():
    reply = request.form['text']
    reply_to_id = request.form['id']
    dt = datetime.now().strftime('%Y-%m-%d %X')
    
    # ... your code here ...
    
    return jsonify({'reply': reply})

I recommend using the submit event of the form.

All form data are serialized using the name attributes and then transferred with ajax. On the server side, the values can in turn be requested using the name.

To suppress the display of certain fields you should use a field of the type "hidden".

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>
    <form name="reply-form" method="post">
      <textarea name="text" placeholder="What's your response to that?"></textarea>
      <input name="url" type="hidden" value="{{ request.url }}" />
      <input name="id" type="hidden" value="{{ post['_id'] }}" />
      <button type="submit">Submit</button>
    </form>

    <script 
      src="https://code.jquery.com/jquery-3.6.0.min.js" 
      integrity="sha256-/xUj 3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" 
      crossorigin="anonymous"
    ></script>
    <script type="text/javascript">
      (function() {
        $(document).ready(() => {
          $('form[name="reply-form"]').submit(function(event) {
            event.preventDefault();
            $.ajax({
              type: 'POST',
              url: '/reply',
              dataType: 'json',
              data: $(this).serialize()
            }).done((data) => {
              console.log(data);
            })
          });
        });
      })();
    </script>
  </body>
</html>

In this way you can easily transfer all values.

  • Related