Kay
Kay

Reputation: 1485

Flask session not persisting value set by ajax if there is no return statement

I am new to web app and I am sorry if this question is totally out of line.

I have a simple ajax call to set states of python flask app as below.

Below is how I set the value

-- setting value --

Javascript (page1.html)

function foo(val1, val2){
   $.ajax({
         url: "./set_option",
         type: "POST",
         data: {arg1:val1, arg2:val2}
   });
}

python side

@app.route('/set_option', methods=['post'])
def set_option():
    session['val1'] = request.form.get('arg1')
    session['val2'] = request.form.get('arg2')

below is how I tried to do something with the value

-- retrieving value --

Javascript (page2.html)

function do_something_with_store_value(){
    $.ajax({
           url:"./print_them",
           type: "POST"
    });
}

python side

@app.route('/print_them', methods=['post'])
def print_them():
    print(session['val1'])
    print(session['val2'])

In above example, I see session['val1'] and session['val2'] do not exist in def print_them(). However, if I modify function foo(val1, val2) to handle return response and def set_option() to return a simple string value session['val1'] and session['val2'] are maintained.

I am very confused about this behavior. I guess I can just use the modification to make it work, but I am really hesitant to do what I do not understand clearly.

Do I have to have return response from flask/python server for session value saving between requests? I thought I could use ajax post call to set state in server side without expecting any data back from the server.

Do I still have to return some sort of success/failure notification to ajax call? what does it have to do with session not keeping the value?

Can somebody please shed some light in this confusion?

Thanks!

Upvotes: 1

Views: 3054

Answers (1)

arshovon
arshovon

Reputation: 13651

Every @app.route decorator should return something.

See the following case.

app.py:

from flask import Flask, request

app = Flask(__name__)

@app.route('/test')
def test():
    print("hello from test")

if __name__ == '__main__':
    app.run(debug = True)

When I tried to access http://localhost:5000/test, it showed

builtins.ValueError
ValueError: View function did not return a response

The exact same scenario is created when your AJAX call is invoked. Moreover, returning some valuable information from Flask will help you to handle errors from jQuery code.

Here is the updated code I have used to eliminate the issue.

app.py:

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

app = Flask(__name__)
app.secret_key = "secret key"

@app.route('/set_session', methods = ['POST'])
def set_session():
    if request.method == 'POST':
        val1 = request.form.get('arg1')
        val2 = request.form.get('arg2')
        session['val1'] = val1
        session['val2'] = val2
        return 'session is set'

@app.route('/get_session', methods = ['GET'])
def get_session():
    if request.method == 'GET':
        data = {}
        try:
            data['val1'] = session['val1']
            data['val2'] = session['val2']
        except:
            pass
        return jsonify(data)

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

if __name__ == '__main__':
    app.run(debug = True)

templates/ajax.html:

<html>
  <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
  </head>
  <body>
    <h3>Session in Flask</h3>
    <div id="session_value"></div>
    <script>
      $(document).ready(function(){
        $.ajax({
          url: '/set_session',
          type: 'POST',
          data: {arg1: 'updated value 1', arg2: 'updated value 2'},
          success: function(result){
            $("#session_value").append(result);
          },
          error: function(result){
            $("#session_value").append(result);
          }
        });
        $.ajax({
          url: '/get_session',
          type: 'GET',
          dataType: 'json',
          success: function(result){
            $("#session_value").append("Val1: "+result.val1);
            $("#session_value").append("Val2: "+result.val1);
          },
          error: function(result){
            $("#session_value").append(result);
          }
        });
      })
    </script>
  </body>
</html>

Upvotes: 2

Related Questions