I've got code that gets JSON data from a PHP script using axios. Currently this call is triggered on input of an input field.
This is fine except the call is triggered every key press. I would like to debounce this function for maybe half a second.
I've tried importing a function from another file that I created called debounce.js which contains:
const debounce = (fn, delay) => {
let timeout
return (...args) => {
if (timeout) {
clearTimeout(timeout)
}
timeout = setTimeout(() => {
fn(...args)
}, delay)
}
}
export default debounce
I want to add the debounce to this method:
async fetchResults(){
await axios.post('includes/searchproducts_json.php', {
// Post data, add value of input to searchterm
searchterm: this.$refs.searchterm.value
})
.then((response)=>{
// Check if status is 200 (OK) and total_results is not 0
// If true show results div and fill data
if (response.status === 200 && response.data.total_results != 0) {
this.showResultDiv = true
this.results = response.data.results
this.totalResults = response.data.total_results
this.finishedCall = true
}else{
this.showResultDiv = false
}
})
.catch((error)=>{
console.log(error)
})
.then((response)=>{
// Get length of returned object and add to results
this.finishedCall = true
})
}
I thought to wrap this debounce function around the entire method because I want to debounce the entire method, not just the retrieving data part. So I tried this:
setup(){
async fetchResults = debounce(() => {
await axios.post('includes/searchproducts_json.php', {
// Post data, add value of input to searchterm
searchterm: this.$refs.searchterm.value
})
.then((response)=>{
// Check if status is 200 (OK) and total_results is not 0
// If true show results div and fill data
if (response.status === 200 && response.data.total_results != 0) {
this.showResultDiv = true
this.results = response.data.results
this.totalResults = response.data.total_results
this.finishedCall = true
}else{
this.showResultDiv = false
}
})
.catch((error)=>{
console.log(error)
})
.then((response)=>{
// Get length of returned object and add to results
this.finishedCall = true
})
}, 500)
return { fetchResults }
}
But I get syntax errors like this. How can I correctly implement this debounce for the entire fetchResults method?
This is my entire JS code without the syntax errors:
import debounce from './assets/js/debounce.js'
let app = Vue.createApp({
data: function(){
return{
// Object to fill with JSON response
results:[],
showResultDiv: false,
totalResults: 0,
finishedCall: false
}
},
puted: {
// Limit total results in searchdropdown to 6
resultsToShow() {
return this.results.slice(0, 6)
},
// Set the actual unlimited result amount to totalResults with matching string
resultString(){
if(this.totalResults == 1){
return this.totalResults + ' resultaat'
}else{
return this.totalResults + ' resultaten'
}
}
},
methods:{
// Function to show div with loading dots until json returned
loadDiv(condition){
this.showResultDiv = condition
},
async fetchResults(){
await axios.post('includes/searchproducts_json.php', {
// Post data, add value of input to searchterm
searchterm: this.$refs.searchterm.value
})
.then((response)=>{
// Check if status is 200 (OK) and total_results is not 0
// If true show results div and fill data
if (response.status === 200 && response.data.total_results != 0) {
this.showResultDiv = true
this.results = response.data.results
this.totalResults = response.data.total_results
this.finishedCall = true
}else{
this.showResultDiv = false
}
})
.catch((error)=>{
console.log(error)
})
.then((response)=>{
// Get length of returned object and add to results
this.finishedCall = true
})
}
}
})
app.mount('#v_search');
I've got code that gets JSON data from a PHP script using axios. Currently this call is triggered on input of an input field.
This is fine except the call is triggered every key press. I would like to debounce this function for maybe half a second.
I've tried importing a function from another file that I created called debounce.js which contains:
const debounce = (fn, delay) => {
let timeout
return (...args) => {
if (timeout) {
clearTimeout(timeout)
}
timeout = setTimeout(() => {
fn(...args)
}, delay)
}
}
export default debounce
I want to add the debounce to this method:
async fetchResults(){
await axios.post('includes/searchproducts_json.php', {
// Post data, add value of input to searchterm
searchterm: this.$refs.searchterm.value
})
.then((response)=>{
// Check if status is 200 (OK) and total_results is not 0
// If true show results div and fill data
if (response.status === 200 && response.data.total_results != 0) {
this.showResultDiv = true
this.results = response.data.results
this.totalResults = response.data.total_results
this.finishedCall = true
}else{
this.showResultDiv = false
}
})
.catch((error)=>{
console.log(error)
})
.then((response)=>{
// Get length of returned object and add to results
this.finishedCall = true
})
}
I thought to wrap this debounce function around the entire method because I want to debounce the entire method, not just the retrieving data part. So I tried this:
setup(){
async fetchResults = debounce(() => {
await axios.post('includes/searchproducts_json.php', {
// Post data, add value of input to searchterm
searchterm: this.$refs.searchterm.value
})
.then((response)=>{
// Check if status is 200 (OK) and total_results is not 0
// If true show results div and fill data
if (response.status === 200 && response.data.total_results != 0) {
this.showResultDiv = true
this.results = response.data.results
this.totalResults = response.data.total_results
this.finishedCall = true
}else{
this.showResultDiv = false
}
})
.catch((error)=>{
console.log(error)
})
.then((response)=>{
// Get length of returned object and add to results
this.finishedCall = true
})
}, 500)
return { fetchResults }
}
But I get syntax errors like this. How can I correctly implement this debounce for the entire fetchResults method?
This is my entire JS code without the syntax errors:
import debounce from './assets/js/debounce.js'
let app = Vue.createApp({
data: function(){
return{
// Object to fill with JSON response
results:[],
showResultDiv: false,
totalResults: 0,
finishedCall: false
}
},
puted: {
// Limit total results in searchdropdown to 6
resultsToShow() {
return this.results.slice(0, 6)
},
// Set the actual unlimited result amount to totalResults with matching string
resultString(){
if(this.totalResults == 1){
return this.totalResults + ' resultaat'
}else{
return this.totalResults + ' resultaten'
}
}
},
methods:{
// Function to show div with loading dots until json returned
loadDiv(condition){
this.showResultDiv = condition
},
async fetchResults(){
await axios.post('includes/searchproducts_json.php', {
// Post data, add value of input to searchterm
searchterm: this.$refs.searchterm.value
})
.then((response)=>{
// Check if status is 200 (OK) and total_results is not 0
// If true show results div and fill data
if (response.status === 200 && response.data.total_results != 0) {
this.showResultDiv = true
this.results = response.data.results
this.totalResults = response.data.total_results
this.finishedCall = true
}else{
this.showResultDiv = false
}
})
.catch((error)=>{
console.log(error)
})
.then((response)=>{
// Get length of returned object and add to results
this.finishedCall = true
})
}
}
})
app.mount('#v_search');
Share
Improve this question
asked Feb 2, 2022 at 10:41
twantwan
2,65912 gold badges42 silver badges115 bronze badges
1
-
the
lodash.debounce
package might be useful, so you don't have to recreate the debounce function: npmjs./package/lodash.debounce – Xavier B. Commented Feb 2, 2022 at 11:20
3 Answers
Reset to default 4You didn't say what syntax error you are having and where.
I found one though and it seems like you are wanting to create a function expression.
Docs: https://developer.mozilla/en-US/docs/Web/JavaScript/Reference/Operators/function
The problem is your syntax:
setup(){
async fetchResults = debounce(() => {
await axios.post('includes/searchproducts_json.php', {
You can't define a function expression with async
and besides, your await
is invalid because the function it lives in doesn't have an async
.
It should be:
setup() {
const fetchResults = debounce(async () => {
await axios.post('')
You can use debounce in Vue 3 like this if you don't want to use any additional packages.
<input type="search" v-model="query" />
const app = Vue.createApp({
data() {
return {
query: "",
results: [],
};
},
methods: {
debounce(func, timeout = 300) {
let timer;
return (...args) => {
clearTimeout(timer);
timer = setTimeout(() => {
func.apply(this, args);
}, timeout);
};
},
fetchResults(query) {
this.debounce(async () => {
await axios
.post("includes/searchproducts_json.php", {
searchterm: query,
})
.then((response) => {
if (response.status === 200 && response.data.total_results != 0) {
this.showResultDiv = true;
this.results = response.data.results;
this.totalResults = response.data.total_results;
this.finishedCall = true;
} else {
this.showResultDiv = false;
}
})
.catch((error) => {
console.error(error);
})
.finally(() => {
this.finishedCall = true;
});
}, 500);
},
},
puted: {
query: {
get() {
return this.query;
},
set(val) {
this.fetchResults(val);
this.query = val;
},
},
},
});
For those who find their way here like me using Vue Composition Api:
<input @input="debounceSearch" v-model="searchstring">
Add lodash in whatever way you like
// bootstrap.js
window._ = require('lodash'); // option1
// yourFile.vue
<script setup>
import _ from 'lodash' // option2
import debounce from 'lodash/debounce' // option3
Call your function
// yourFile.vue
// for option 1 & 2
const debounceSearch = _.debounce(() => {fetchResults();}, 400)
// For option 3
const debounceSearch = debounce(() => {fetchResults();}, 400)
const fetchResults = () => {
// run your axios.post(url, data) code here
}
</script>
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1742284421a4415069.html
评论列表(0条)