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:
JavaScript
x
14
14
1
lookup.addEventListener('keyup', e => {
2
3
let searchValue = e.target.value;
4
5
if (searchValue.length > 4){
6
7
setTimeout(() => {
8
9
fetch(`{% url 'find_book' %}?param=${e.target.value}` )
10
.then(res => res.json())
11
.then(data => console.log(data))
12
.catch(err => console.log(err))}, 2000);
13
}
14
views.py
JavaScript
1
17
17
1
@api_view(['GET'])
2
def find_book(request):
3
4
param = request.GET.get("param")
5
6
if param:
7
url = f'https://www.googleapis.com/books/v1/volumes?q=intitle:{param}&key=xxx'
8
r = requests.get(url)
9
10
if r.status_code == 200:
11
data = r.json()
12
return Response(data, status=status.HTTP_200_OK)
13
else:
14
return Response({"error": "Request failed"}, status=r.status_code)
15
else:
16
return Response({}, status=status.HTTP_200_OK)
17
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:
JavaScript
1
18
18
1
let delayedFetch;
2
3
lookup.addEventListener('keyup', e => {
4
5
let searchValue = e.target.value;
6
7
if (searchValue.length > 4){
8
9
if (delayedFetch) clearTimeout(delayedFetch);
10
11
delayedFetch = setTimeout(() => {
12
13
fetch(`{% url 'find_book' %}?param=${e.target.value}` )
14
.then(res => res.json())
15
.then(data => console.log(data))
16
.catch(err => console.log(err))}, 2000);
17
}
18