user17252149
user17252149

Reputation: 31

Why is my fetch request being sent multiple times?

I am trying to make it possible to comment on the site. If I post the first comment, it posts fine. If posting the second one, fetch sends 2 requests and displays the same comment 2 times, the third comment 3 requests and displays 3 times, etc. What do I need to do for everything to work?

js

function insertNewComment(data) {
    var ul = document.getElementById("new-comment");
    ul.insertAdjacentHTML('afterBegin', '<li class="list-group-item">' + data.text + '</li>');
}


function sendComment() {
    document.getElementById('comment').addEventListener('submit', (e) => {
        e.preventDefault();
        const formData = new FormData(e.target);
        fetch(e.target.getAttribute('action'), {
            method: e.target.getAttribute('method'),
            body: formData
        })
        .then((response) => {
            return response.json();
        })
        .then((data) => {
            insertNewComment(data);
            document.getElementById('comment').reset();
        });
    });
}

html

{% extends 'base.html' %}

{% block other_resources %}
    <link rel="stylesheet" href="{{ url_for('.static', filename='css/post.css') }}">
    <script src="{{ url_for('.static', filename='js/post.js') }}"></script>
{% endblock %}

{% block content %}
    <div class="card">
      <img src="{{ post.photo_path }}" class="card-img-top" alt="...">
      <div class="card-body">
        <h5 class="card-title">{{ post.title }}</h5>
        <p class="card-text">{{ post.text }}</p>
        <p class="card-text"><small class="text-muted">{{ post.created }}</small></p>
      <div class="card-header">
          Написать комментарий:
      </div>

        <div>
            <form action="{{ url_for('news.add_comment', post_id=post.id) }}" id='comment' method="POST">
              {{form.csrf_token}}
              <div class="form-floating">
                {{form.text(class='form-control')}}
                {{form.text.label(for="floatingTextarea2")}}
              </div>
              {{form.submit(class="btn btn-dark send-comment", onclick='sendComment()')}}
              <div class="form-floating">
                <label for="floatingTextarea2">Комментарий</label>
              </div>
            </form>
          </div>
          <div class="card comments">
          <div class="card-header">
            Комментарии:
          </div>
          <ul class="list-group list-group-flush" id='new-comment'>
            {% for c in comments %}
               <li class="list-group-item">{{ c.text }}</li>
            {% endfor %}
          </ul>
        </div>
        </div>
    </div>
{% endblock %}

Upvotes: 3

Views: 2156

Answers (1)

connexo
connexo

Reputation: 56750

Every time you execute sendComment you add another submit listener to that form.

Make sure you only add one listener:

    function sendComment(e) {
        e.preventDefault();
        const formData = new FormData(e.target);
        fetch(e.target.getAttribute('action'), {
            method: e.target.getAttribute('method'),
            body: formData
        })
        .then((response) => {
            return response.json();
        })
        .then((data) => {
            insertNewComment(data);
            document.getElementById('comment').reset();
        });
    };
    // add the listener outside of `sendComment`
    document.getElementById('comment').addEventListener('submit', sendComment);

Upvotes: 3

Related Questions