3

I am trying to call a function in Flask by clicking a button. When the button is clicked, the following script runs.

JS

$("#load_btn").click(function() {
    $.get("/callback");
}

Flask

@app.route('/callback')
def callback():
    print('called')
    ... # code here that needs to run before rendering callback
    return render_template('callback.html')

The problem here is, called is printed, and GET /callback HTTP/1.1 200 is logged as well, but callback.html is not rendered - the page stays the same. I'm guessing this is probably not the best approach to solving this problem, but if so what is the recommended approach?

Sudeep
  • 796
  • 6
  • 16

1 Answers1

5

$.get just sends an HTTP request to your server, but doesn't actually do anything anything with the data (in your case, the rendered template) it gets back from the server.

Try something like this:

$("#load_btn").click(function() {
    $("html").load("/callback");
}

Or if the template you render doesn't contain any <head> tags, only body content, you can do

$("#load_btn").click(function() {
    $("body").load("/callback");
}

Or, you can exchange "body" for a specific element to only replace a specific part of the page.

If you want the user to be redirected, do this:

$("#load_btn").click(function() {
    window.location = "/callback";
}
bigblind
  • 12,539
  • 14
  • 68
  • 123
  • This replaces the content in the current page. I would like the user to be redirected to mysite.com/callback and have `callback.html` rendered for that page, if that makes sense. The reason I'm sending it back through the flask application and not loading it directly in HTML is because I need to run a function within callback. – Sudeep Jun 20 '17 at 00:03
  • I've updated my answer – bigblind Jun 20 '17 at 00:06
  • 1
    Thanks, that changes the url, but it still doesn't solve my problem. I'm looking for the redirection to happen after the code in the `callback` method has been executed (I've represented that by `...` in my original post.). – Sudeep Jun 20 '17 at 00:12
  • Yes, that's what's happening. When the user clicks the `#load_btn` element, the click handler is called, which changes the url. The browser fetches the contents of this url from the server. Then, whatever code you have in your `callback` function runs. Then, the template is rendered, and the response is sent to the browser – bigblind Jun 20 '17 at 00:19
  • You can't have the redirection happen after the `callback` function runs, since the only way this callback function gets run, is by going to the url `/callback`. – bigblind Jun 20 '17 at 00:21
  • Oh okay, got it. The process in callback is a long running function though. I have a progress bar which I would ideally like to be updating while the code in callback is running, but if I call `window.location`, it won't run. Any way around that? – Sudeep Jun 20 '17 at 00:26
  • 1
    HTTP is a very simple protocol based on requests and responses. So when the user goes to `/callback`, your callback function can send only one response. There are a couple of ways to do it, but the simplest way to do it would be to have the `callback` function run your long-running task in a background thread, and then immediately return the response template which contains your progress bar. That page would then need to send requests to the server (using `$.get`) to ask for progress. You'd create a flask route like `/callback_progress`that returns this information. – bigblind Jun 20 '17 at 00:35