#TextInput #onKeyPress #debounce #setTimeout
Dedicated to Andreas Kviby.
If you’ve ever inspected the TexInput’s value when the onKeyPress() event handler is triggered, you were probably puzzled by the lack of the last entered character.
Try it yourself with console.log() output - something like this:
export function input1_keyPress(event, $w) {
let val = $w('#input1').value;
console.log(val);
}
The console output will always be one character behind.
So what gives? You just need to wait a bit for the value to be updated. Use setTimeout() to introduce a small delay:
export function input1_keyPress(event, $w) {
setTimeout(() => {
let val = $w('#input1').value;
console.log(val);
}, 10); // 10 milliseconds works for me
}
Lo and behold, the console output is correct each time it’s triggered.
Even though this works, you might need a more robust delay mechanism. Let’s say for example that you’ve got an autocomplete routine that queries a database or external web service. If the user types too quickly, it might cause overlapping queries - not a pretty sight. So, we can use a more robust mechanism - debounce:
let debounceTimer;
export function input1_keyPress(event, $w) {
if (debounceTimer) {
clearTimeout(debounceTimer);
debounceTimer = undefined;
}
debounceTimer = setTimeout(() => {
let val = $w('#input1').value;
console.log(val);
// some sort of query that might overlap execution
}, 500); // 500 milliseconds works for me, your mileage may vary
}
As with the simple setTimeout() method above, this introduces a delay which allows the input field to update its value. However, it has an additional advantage in that it prevents calling the service query too quickly in succession. You might need to adjust the timeout based on the query service.
Now, go have fun.