javascriptajaxflaskflask-sqlalchemyflask-wtforms

flask issue got ImmutableMultiDict([])


Dears, I am new in Flask and I got an issue with sending ajax request as data was sent from Ajax and when I validated it I got ImmutableMultiDict([]) as validation error raised as the input field is empty. I need help to solve this issue. regards.

here is my code :

@users.route('/updateUserPassword',methods=['POST'])
@login_required
def updateUserPassword() :
    message=''
    status=''
    print(request.form)
    passwordform = changeUserPassword(request.form)
    if passwordform.validate_on_submit() :
        id        = request.form.get('id')
        action    = request.form.get('action')
        password  = request.form.get('password')
        pass_confirm  = request.form.get('pass_confirm')
 
         
    else:   
       # return jsonify({'status':'error',
              #   message:[{passwordform[field].label.text: ', '.join(errors)} for field, errors in passwordform.errors.items()]})
        errors = {}
        for field, field_errors in passwordform.errors.items():
            errors[field] = [str(error) for error in field_errors]
        return jsonify({'error': "error submit data ", 'message': errors})

my js code is :

$("#editUserForm").submit(function(){

var formData = $(this).serialize();
var allData  = formData + "&action=editPass";
$.ajax({
url: "{{ url_for('users.updateUserPassword') }} ",
  type:"POST",
  data: JSON.stringify(allData),
  contentType: 'application/json',

  beforeSend:function(){
  },
  statusCode: {
      404: function() {
          alert( "page not found" );
      },
  },
  success:function(valdata) {
  
      if(valdata['status'] == "success")
      {
          $("#updatePasswordResult").html(valdata['message']);
          setTimeout(function(){$('#changepassword').modal('hide');}, 2000);
      }else{
        var errors = valdata['message'];
                          for (var field in errors) {
                              if (errors.hasOwnProperty(field)) {
                                  var errorMessages = errors[field];
                                  for (var i = 0; i < errorMessages.length; i++) {
                                      $('#updatePasswordResult').append('<p>' + field + ': ' + errorMessages[i] + '</p>');
                                  }
                              }
                            }

        //  $("#updatePasswordResult").html(valdata['message']);
      }
  }
});
return false;
});

validation code is :

class changeUserPassword(FlaskForm):

    password = PasswordField("Password",validators=[DataRequired()])                
    pass_confirm = PasswordField('Confirm Password',validators=[DataRequired(),EqualTo('password',message='Passwords must match!')])
   
    submit = SubmitField('Submit')  

Solution

  • When you are sending the AJAX request, you are sending a JSON with the header "Content-Type: application/json" and in your Flask code you are trying to read from request.form.

    If you want to read the JSON you are sending in Flask then you need to call request.json instead. So it can parse the JSON.

    from flask import request
    
    def update_user_password():
        print(request.json)
        # {'id': 1, 'action': 'editPass', 'password': 'hunter2', 'pass_confirm': 'hunter2'}
    
        user_id = request.json.get("id") # 1
        action = request.json.get("action") # "editPass"
        password = request.json.get("password") # "hunter2"
        pass_confirm = request.json.get("pass_confirm") # "hunter2"