javascriptdjangodomcsrf-token

getCSRFToken is not defined error, JavaScript


This is the part of the code in the Django + JavaScript Todo App that is responsible for deleting a note. I need a csrftoken for this, but the JS is showing me an error in the console. What did I do wrong and how can I fix it?

Uncaught ReferenceError: getCSRFToken is not defined at HTMLButtonElement. (main.js:100:30)

const deleteBtn = document.getElementById("deleteBtn");
const delUrl = document.body.dataset.delNoteUrl;

deleteBtn.addEventListener("click", (e) => {
  e.preventDefault();

  if (e.target.classList.contains("delete-btn")) {
    const parentLi = e.target.closest(".todo__note");
    const noteId = parentLi.getAttribute("data-id");

    fetch(`${delUrl}/${noteId}`, {
        method: "POST",
        headers: {
          "X-CSRFToken": getCSRFToken(),
        },
      })
        .then((response) => response.json())
        .then((data) => {
          if (data.status == "success") {
            parentLi.remove();
          }
        });
  }
});

Here is HTML, if need.

<ul class="todo__list">
  {% for note in notes %}
  <li class="todo__note flex" data-id="{{ note.id }}">
    <div>
      <input type="checkbox" />
      <span>{{ note.text }}</span>
    </div>
    <div class="delete__edit">
      <button class="edit-btn" id="editBtn">
        <img src="{% static 'images/edit.svg' %}" alt="" />
      </button>
      <button class="delete-btn" id="deleteBtn">
        <img src="{% static 'images/delete.svg' %}" alt="" />
      </button>
    </div>
  </li>
  {% endfor %}
</ul>

Solution

  • As the error says, you use a function getCSRFToken but you did not define such function. The function might be defined somewhere, but then it is in a JavaScript file that is not imported (before you run this function).

    The Django documentation shows a hint how to get the CSRF token:

    function getCookie(name) {
        let cookieValue = null;
        if (document.cookie && document.cookie !== '') {
            const cookies = document.cookie.split(';');
            for (let i = 0; i < cookies.length; i++) {
                const cookie = cookies[i].trim();
                // Does this cookie string begin with the name we want?
                if (cookie.substring(0, name.length + 1) === (name + '=')) {
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                }
            }
        }
        return cookieValue;
    }
    const csrftoken = getCookie('csrftoken');
    

    we thus can define a function for this with:

    function getCookie(name) {
        let cookieValue = null;
        if (document.cookie && document.cookie !== '') {
            const cookies = document.cookie.split(';');
            for (let i = 0; i < cookies.length; i++) {
                const cookie = cookies[i].trim();
                // Does this cookie string begin with the name we want?
                if (cookie.substring(0, name.length + 1) === (name + '=')) {
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                }
            }
        }
        return cookieValue;
    }
    
    function getCSRFToken() {
        return getCookie('csrftoken');
    }