Почему мой запрос на извлечение отправляется несколько раз?

#javascript #fetch #fetch-api

Вопрос:

Я пытаюсь сделать возможным комментировать на сайте. Если я опубликую первый комментарий, он будет опубликован нормально. При публикации второго, fetch отправляет 2 запроса и отображает один и тот же комментарий 2 раза, третий комментарий запрашивает 3 и отображает 3 раза и т. Д. Что мне нужно сделать, чтобы все работало?

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 %}

 

Ответ №1:

Каждый раз, когда вы выполняете sendComment , вы добавляете к этому еще submit одного слушателя form .

Убедитесь, что вы добавили только одного слушателя:

     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);