0

My vue learning curve: I noticed that the input filed sends a call via ajax (axios) to YouTube on every key entered in the input filed. So one letter it already perform the search over in YouTube search APi. I am guessing that for using this method to search over a database by keywords and etc this would have worked perfectly but when using API such as YouTube videos it should work better if it could wait until the user finish up his search query. So my question is there a directive or any other way to force the API call to wait for the user to finish up his search query before it runs the call over in YouTube? BTW I am exceeding my 1,000 limit over YouTube API in like 1 hour while testing.

This is the App.vue

<template>
  <SearchBar @emitTermSearch="onTermSearch"></SearchBar>
  <VideoList :videos="videos"></VideoList>
</template>

<script>
import axios from "axios";
import SearchBar from "./components/SearchBar";
const API_KEY = "hidden";
export default {
  name: "App",
  components: {
    SearchBar
  },
  data() {
    return {
      videos: []
    };
  },
  methods: {
    onTermSearch(emitTermSearch) {
      axios
        .get("https://www.googleapis.com/youtube/v3/search", {
          params: {
            key: API_KEY,
            type: "video",
            part: "snippet",
            maxResults: 2,
            order: "date",
            q: emitTermSearch
          }
        }.then(response => {
          this.videos = response.data.items;
        }).catch(err => {
          console.log(err);
        });
    }
  }
};
</script>

This is the SearcBar.vue

<template>
  <h1>Please Search</h1>
  <div id="searchbar">
    <input @input="onInput" />
  </div>
</template>

<script>
export default {
  name: "SearchBar",
  methods: {
    onInput(event) {
      this.$emit("emitTermSearch", event.target.value);
    }
  }
};
</script>
Nikola Pavicevic
  • 21,952
  • 9
  • 25
  • 46
Refael
  • 145
  • 2
  • 12
  • Does this answer your question? [How to implement debounce in Vue2?](https://stackoverflow.com/questions/42199956/how-to-implement-debounce-in-vue2) – Matt U Aug 28 '21 at 13:59
  • I know you're on Vue3, but that debounce solution should still do the trick. You may or may not need to make minor adjustments, as the linked answer is Vue2. – Matt U Aug 28 '21 at 13:59

2 Answers2

1

Instead of onInput on @input, you can emit your event on @keyup.enter (or some other key), or add a button with a @click event.

Another approach is to set a timeout:

onInput(event) {
  setTimeout(() => {
    this.$emit("emitTermSearch", event.target.value);
  }, 700)
}
StevenSiebert
  • 1,306
  • 4
  • 15
  • 26
Nikola Pavicevic
  • 21,952
  • 9
  • 25
  • 46
  • Hi Nikola, Thank you. Using your suggestions above, beside adding a submit button, did not work as it still sends a request response on every entered keyword. I have used, for now, the "keyup.f1" so i can have more control on the number of the requests before I end the api quota just for learning purposes. – Refael Aug 28 '21 at 13:36
  • You are welcome mate :) If you add button then you need to remove `@input` and instead make `@click ` event – Nikola Pavicevic Aug 28 '21 at 13:45
0

Here you go:

Vue.config.productionTip = false
Vue.config.devtools = false


new Vue({
  el: "#app",
  data: {
    typingInterval: 500,
    searchQuery: "",
    typingTimer: "",
  },
  methods: {
    searchData(){
      clearTimeout(this.typingTimer);
      if (searchQuery) {
          this.typingTimer = setTimeout(this.searchApi, this.typingInterval);
      }
     },
     
    searchApi(){
      console.log(`Searching data for keyword: ${searchQuery}`);
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <input placeholder="search here" v-model="this.searchQuery" @keyup="searchData()">
</div>
Salvino D'sa
  • 4,018
  • 1
  • 7
  • 19