miguelgrinberg / turbo-flask

Integration of Hotwire's Turbo library with Flask.
MIT License
301 stars 35 forks source link

Error: Form responses must redirect to another location #11

Closed Alexsik76 closed 3 years ago

Alexsik76 commented 3 years ago

Hello! As I understand it, there is a problem in the operation of turbo.js when processing a form if it is not valid. In this case, without receiving a redirect, turbo.js generates an error: "Error: Form responses must redirect to another location". The only working solution for me is to disable turbo-frame in forms: "data-turbo =" false "". https://github.com/hotwired/turbo-rails/issues/122 Is there another way?

miguelgrinberg commented 3 years ago

Based on this comment it seems you have to return a 422 status code when you want to return HTML after a form submission. Have you tried that?

Alexsik76 commented 3 years ago

Thanks for the answer. This looks like an issue https://github.com/miguelgrinberg/turbo-flask/issues/5 . In my case, the code:

    if form.validate_on_submit():
        img = form.img.data
        filename = secure_filename(img.filename)
        if os.path.splitext(filename)[1] != validate_image(img.stream):
            flash('Files content is not valid!', 'danger')
            return render_template('create_post.html', form=form)

does not work, no messages are displayed, and an error message appears in the JS console. With this addition

return render_template('create_post.html', form=form), 422

everything works well.

Alexsik76 commented 3 years ago

But this also means that, when using turbo.js, in the standard route pattern like

    if form.validate_on_submit():
        user.set_password(form.password.data)
        db.session.commit()
        flash('Password was changed. You can log in', 'success')
        return redirect(url_for('main.index'))
return render_template('auth/new_password.html', form=form)

, you always need to add

    if form.validate_on_submit():
        user.set_password(form.password.data)
        db.session.commit()
        flash('Password was changed. You can log in', 'success')
        return redirect(url_for('main.index'))
    elif form.is_submitted():
        return render_template('auth/new_password.html', form=form), 422
return render_template('auth/new_password.html', form=form)

?

miguelgrinberg commented 3 years ago

I don't think this needs to be done always. My understanding is that this problem only occurrs when you don't have your form inside a <turbo-frame> element. Are you using turbo frames and still getting issues with your responses?

Alexsik76 commented 3 years ago

I am trying to use only to display information about users like

index.html:

{% block content %}
    <div class="container">
    <div id="user-actions-info"> <!-- turbo's target -->
        {% with messages = get_flashed_messages(with_categories=true) %}
            {% if messages %}
                {% for category, message in messages %}
                    <div class="alert alert-{{ category }}" role="alert">{{ message }}</div>
                {% endfor %}
            {% endif %}
        {% endwith %}
    </div>

in _createapp:

def live_log_in_info(app):
    @user_logged_in.connect_via(app)
    def log_in_info(sender, user):
        turbo.push(turbo.append(render_template('auth/_user_logged_in.html', user=user), 'user-actions-info'))

    @user_logged_out.connect_via(app)
    def log_out_info(sender, user):
        turbo.push(turbo.append(render_template('auth/_user_logged_out.html', user=user), 'user-actions-info'))
miguelgrinberg commented 3 years ago

I'm sorry but I don't understand. Are you using <turbo-frame> for your form or not? The problem with the redirects only occurs when turbo frames are not used, I believe.

Alexsik76 commented 3 years ago

I don't use <turbo-frame> for forms.

miguelgrinberg commented 3 years ago

@Alexsik76 And have you considered putting the form inside a turbo frame? That eliminates this problem.

Alexsik76 commented 3 years ago

Thanks for your answers and your patience. The <turbo-frame> tag really works and fixes the problem with forms.