Search code examples
javascriptpythonflaskxmlhttprequestflask-sqlalchemy

Send dictionary via http post request from Javascript to python


I'm using flask and sqlalchemy inside sublime text to create a simple web application. In 'studentscreen.html', there are multiple html elements (post-it notes/sticky notes) made up of a title and some text. These are created using a for loop. Like so:

<ul id='postlist'>

        {% for post in posts %}

            {% if loggedIn == True: %}


                {% if post[3] == True: %}

                  <li>
                    <a>
                        <h2 onkeypress="return (this.innerText.length <= 15)" contenteditable="true" onblur="saveText()">{{post[1]}}</h2>
                        <p onkeypress="return (this.innerText.length <= 60)" contenteditable="true" onblur="saveText()">{{post[2]}}</p>
                    </a>
                  </li>

    <!-- etc... -->

Using 'onblur', the Javascript function named saveText() is called.

This function is supposed to retrieve the "h2" text as well as the "p" text for any notes that have been created and send it to my 'routes.py' document using an http post request. (I'm unsure about how to do an ajax request.)

Now, I retrieve the contents for each post like so:

function saveText(){
    
            let postsRef  = document.getElementById('postlist').getElementsByTagName('li');
    
            var text = [];
            var title = [];
    
            for (let i = 0; i < postsRef.length; i++) {
                text.push([postsRef.item(i).getElementsByTagName('p')[0].innerHTML]);
            }
    
            for (let i = 0; i < postsRef.length; i++) {
                title.push([postsRef.item(i).getElementsByTagName('h2').[0].innerHTML]);
            }
    
    /* etc... */

This creates two arrays; text and title holding all texts' and titles'. I'm trying to send this information to 'routes.py' like so:

var http = new XMLHttpRequest();
var url = "/newtext";
http.open ("POST", url, true);
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.send(/* something! */);

I don't know what to pass in to .send(). Furthermore I don't know how to receive the information to be sent. Now I have the following:

@app.route("/newtext", methods = ["POST", "GET"])
    def newText():

        if request.method == "POST":
            data = request.form


    # etc... #

I have tried different alternatives like request.form.get(), request.value and request.form.get('name') (creating a dictionary with a key named 'name' in 'studentscreen.html').

Sometimes it returns stuff like this:

'None', 
{}, 
ImmutableMultiDict([]), 
CombinedMultiDict([ImmutableMultiDict([]), 
ImmutableMultiDict([('object Object', '')])])

Please let me know how to format the content and perform the post request and receive it in python.

Thank you! /William


Solution

  • In the send function you need to send xml form.

    http.send(`title=${title}&text=${text}`); 
    

    The one inside ${} are the lists.

    In flask you can access it using

    request.form.get("title")
    request.form.get("text")
    

    Edit : ajax version

    Include jquery in your html

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    
    
    $.ajax({
        type: "POST",
        url: url,
        data: JSON.stringify({titles: title, contents: text}),
        contentType: "application/json; charset=utf-8"
        success: function(response){
         
        }
      });
    

    When accessing this in python you need to use getlist

    request.get_json()['titles']
    request.get_json()["text"]