0👍
I believe all the problems with the search bar have been solved: Demo here
I added comments to the code so it should be clear how it works.
In searchbar.vue:
<template>
<v-autocomplete
clearable
:loading="isLoading"
:items="games"
:search-input.sync="search"
hide-details
item-text="name"
item-value="id"
label="Search for a Game..."
solo-inverted
></v-autocomplete>
</template>
<script>
import _ from "lodash";
export default {
data: () => ({
games: [], // this is where all the game data will be stored
isLoading: true, // variable to determine if the results are still being fetched from the API
search: null // this is where the query will be stored
}),
methods: {
getGames(params = "") {
// this function will fetch game data from https://api.rawg.io/api/games with whatever api parameters you pass to the parameter `params`
this.axios
.get("https://api.rawg.io/api/games" + params)
.then(resp => {
// fetch data
let tempGames = [...this.games.slice(0), ...resp.data.results]; //copy of this.games + new data
this.games = _.uniqBy(tempGames, "id"); // remove any duplicates
this.isLoading = false; // now that the data is in the array `games`, we can set isLoading to false
})
.catch(e => {
// code to run if there was an error
console.error(e); // display error message
});
},
searchGames(query) {
// this function will call getGames() with the search query formatted as an API parameter (?search=YOUR_QUERY)
let searchQuery = encodeURI("?search=" + query); // URI encode the query so it is able to be fetched properly
this.getGames(searchQuery);
}
},
watch: {
search: _.debounce(function(query) {
// debounce with a a value of 250 will allow this function to be every 250 milliseconds at most. So if the user is typing continually, it won't run until the user stops.
this.searchGames(query);
}, 250)
},
created() {
this.getGames(); // load the first 20 games initally
}
};
</script>
This will:
- Load the first 20 games
- When you enter a query and stop typing, it will perform a request to
https://api.rawg.io/api/games?search=YOUR_QUERY
, and add the results to thegames
array. (So each time you search for something, the saved games array increases. That means that if you search for the same game twice, while it will still search online withhttps://api.rawg.io/api/games?search=YOUR_QUERY
, the game will have been already in the games array from the first time, so it will be loaded immediately.) v-autocomplete
filters and displays the results.
This method will work better on faster connections, as the results are loaded faster. So if you have a slow connection, it may take time for the results to load. Unfortunately that’s something that can’t be worked around (although you could load a lot of data beforehand, but there’s no guarantee that what you load is what the user will search for)
The graphical problem with the navbar was resolved by changing the parent <div>
in App.vue to <v-app>
, like so:
Before:
<template>
<div id="app">
<nav-bar></nav-bar>
...
</div>
</template>
After:
<template>
<v-app id="app">
<nav-bar></nav-bar>
...
</v-app>
</template>
I also added lodash
as a dependency for debouncing (waiting until the user stops typing) and removing duplicates.
Here’s the codepen I was working on.
Do let me know if you have any further questions.