1

I have a page with a button that makes a ajax post to a flask route. I'd like the route to compute a message (simplified by hardcoding for the example) and passes it back to another route and reloads the page the user is on. redirect(urlfor()) does call the other route, but render_template seems not to be called as the page doesn't reload.

init.py

from flask import Flask, render_template, request, redirect, url_for

app = Flask(__name__)


@app.route('/second_route', methods=['POST'])
def second_route():
    print request.json
    return redirect(url_for('hello_world', message='test'))


@app.route('/')
def hello_world(message=None):
    return render_template('index.html', message=message)


app.run()

index.html

<html>
<head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>


    <script>
        $(document).ready(function () {
            $('#mybutton').click(function () {
                $.ajax({
                    type: "POST",
                    contentType: "application/json; charset=utf-8",
                    url: "/second_route",
                    data: JSON.stringify({}),
                    success: [],
                    dataType: "json"
                });

            });
        });


    </script>
</head>
<body>
{{ message }}
<button id="mybutton" name="mybutton" type="button">Click Me!</button>
</body>
</html>
user2242044
  • 8,803
  • 25
  • 97
  • 164

2 Answers2

1

AJAX cannot handle a redirect response, afaik. You could, though, encapsulate {{message}} in a <span id="message">, identify the element, and do a jQuery .html() to insert custom text upon AJAX completion success.

$.ajax({
   type: "POST",
   contentType: "application/json; charset=utf-8",
   url: "/second_route",
   data: JSON.stringify({}),
   success: [],
   dataType: "json"
}).done(function(){
   $('#message').html('test');
   window.location.href = '/';
}).fail(function(response){
   $('#message').html(response['responseText']);
});

To redirect, you'd replace the code inside the done clause with window.location.href = "/someURL", but since the endpoint is the same this isn't necessary. This way, using a message variable at all wouldn't be necessary.

Mangohero1
  • 1,832
  • 2
  • 12
  • 20
  • so this was a simplified example. `second_route` is used to push data to a database. `message` is used to return the success of that data and reloading the page will requery a bunch of stuff from the database, so the `done` function with the div tag (while works in this example) will not work in my application. if I used `window.location.href` then I wouldn't have access to the message. Sorry my simple example oversimplifies things. – user2242044 Dec 28 '17 at 18:40
  • just to clarify, are you querying the database when loading `index.html` initially? I think including both was what you needed. Included clause in case AJAX call ran into an error. – Mangohero1 Dec 28 '17 at 19:11
  • I'm not sure save the message in `done` then reloading the `/` route works because that overwrites the message. – user2242044 Dec 28 '17 at 19:19
  • Yes I am querying initially – user2242044 Dec 28 '17 at 19:25
  • is anything from the database being rendered to the template? because if so, then you could re-query the database after you've pushed data to it in the same route, and return a `JSON` object (which could incorporate success or failure text) . This wouldn't reload the page, however (which at this point, depends if that's desirable or not) – Mangohero1 Dec 28 '17 at 19:25
  • it wouldn't reload the page, but it would update the page without having to refresh – Mangohero1 Dec 28 '17 at 19:26
  • yeah I that might work. I think maybe the easiest approach for my application would be to just post to the same route that loads the page – user2242044 Dec 28 '17 at 19:30
  • alright, let me know how that works. I'm interested in your approach as well. good luck! – Mangohero1 Dec 28 '17 at 19:34
  • added my solution as an answer. check it out. – user2242044 Dec 28 '17 at 19:44
1

This is how I ended up solving the issue for those reading the question.

Changing my post request to post to the same route the loads the page with this call:

 var posting = $.post(window.location.href, {'some key': 'some value'});
                posting.done(function( ) {
                    window.location.replace(window.location.href);
                });
user2242044
  • 8,803
  • 25
  • 97
  • 164
  • Ah that's how it's done. the `window.location.replace()` was new to me. guess we both learned something! UV'd – Mangohero1 Dec 28 '17 at 19:52