This might be far from how it should be done, I’m learning on the go and it’s my first time trying something like this.
Problem: Even with the setTimeout function, server sends response for each letter I have written, though I would expect it to wait for user to stop typing and just fetch the finished word(s)
Script in my template:
lookup.addEventListener('keyup', e => { let searchValue = e.target.value; if (searchValue.length > 4){ setTimeout(() => { fetch(`{% url 'find_book' %}?param=${e.target.value}` ) .then(res => res.json()) .then(data => console.log(data)) .catch(err => console.log(err))}, 2000); }
views.py
@api_view(['GET']) def find_book(request): param = request.GET.get("param") if param: url = f'https://www.googleapis.com/books/v1/volumes?q=intitle:{param}&key=xxx' r = requests.get(url) if r.status_code == 200: data = r.json() return Response(data, status=status.HTTP_200_OK) else: return Response({"error": "Request failed"}, status=r.status_code) else: return Response({}, status=status.HTTP_200_OK)
Advertisement
Answer
Store timeout id to variable in the scope higher than yours event listner. When event fires up – check if there was a timeout and clear it (which means cancel the request if it wasn’t yet executed)
Example:
let delayedFetch; lookup.addEventListener('keyup', e => { let searchValue = e.target.value; if (searchValue.length > 4){ if (delayedFetch) clearTimeout(delayedFetch); delayedFetch = setTimeout(() => { fetch(`{% url 'find_book' %}?param=${e.target.value}` ) .then(res => res.json()) .then(data => console.log(data)) .catch(err => console.log(err))}, 2000); }