Tengo una función JS en mi plantilla que funciona con comandos de búsqueda para transmitir a una vista de Django. La parte extraña es que es como se esperaba la mayor parte del tiempo, pero a veces simplemente no es así y no puedo entender por qué.
JS en la plantilla:
<script> if (document.querySelectorAll(".nav-link")[1].innerHTML != "Log In") { var like = document.querySelector(".likes"); var quantity = document.querySelector(".quantity"); like.addEventListener("click", () => likes()) function likes () { fetch(`/likes/${like.value}`, { method: "PUT"}); if (like.innerHTML.slice(0, 2) != "Un") { like.innerHTML = "Unlike 💔"; } else { like.innerHTML = "Like ❤"; } fetch(`/likes/${like.value}`) .then(response => response.json()) .then(post => { console.log(post["liked"]); quantity.innerHTML = post["liked"].length; }); } } </script>mi vista:
@csrf_exempt @login_required def likes(request, id): user = User.objects.get(username=request.user) try: post = Post.objects.get(pk=id) except Post.DoesNotExist: return JsonResponse({"error": "No such post"}, status=404) if request.method == "GET": return JsonResponse(post.serialize()) if request.method == "PUT": #data = json.loads(request) if user not in post.liked.all() and post.poster != user: print("adding") post.liked.add(user) post.save() else: print("removing") post.liked.remove(user) post.save() return HttpResponse(status=204)Debería estar alternando entre una lista vacía y una lista que contiene un dos.
Sin embargo, puede ver que, aunque generalmente funciona bien, tiene un lugar donde hay varios "[2]" seguidos y, a veces, también tiene varios "[]" seguidos.
En realidad, esto solo comenzó después de agregar la segunda búsqueda, pero no puedo entender por qué; antes de eso alternaba sin problemas.
Como dijo @Jared Smith en los comentarios, no hay una orden de fetch garantizada, ya que es asíncrona, para controlar la orden, use async y await el resultado de la respuesta, algo como esto:
like.addEventListener("click", async () => await likes()) async function likes () { await fetch(`/likes/${like.value}`, { method: "PUT"}); if (like.innerHTML.slice(0, 2) != "Un") { like.innerHTML = "Unlike 💔"; } else { like.innerHTML = "Like ❤"; } await fetch(`/likes/${like.value}`); const post = await response.json(); quantity.innerHTML = post["liked"].length; }