My code fires a new ajax request on every single keystroke and i don’t know how to make my api fetch once, and then have the input event do the filtering.
My code works fine , but if i would live it like that it would take years to load when i would have a large json content.
The states.json data is still the same (and usualy is in autocomplete), i should load it once instead of every keystroke. Extra request for each key is not a good idea. So can someone please help me?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="css/main.css">
<title>Test</title>
</head>
<body>
<div class="container">
<div class="search-wrapper">
<input type="text" name="" autocomplete="off" id="search" placeholder="Search now">
<ul class="match-list">
</ul>
</div>
</div>
<script src="function.js"></script>
</body>
</html>
and here is my javascript
const search = document.querySelector("#search");
const matchList = document.querySelector(".match-list");
// search states.json and filter it
const searchStates = async searchText => {
const res = await fetch('data/states.json');
const states = await res.json();
//Get matches to current text input
let matches = states.filter(state => {
const regex = new RegExp(`^${searchText}`, 'gi');
return state.name.match(regex) || state.abbr.match(regex);
});
if (searchText.length === 0) {
matches = [];
};
outputHtml(matches)
};
//show results in html
const outputHtml = matches => {
if (matches.length > 0) {
const html = matches.map(match =>`
<li class="match-list-element">
<h4 class="">${match.name} (${match.abbr})</h4>
<span class="">${match.capital}</span>
<small class="">Lat:${match.lat}/ Long: ${match.long}</small>
</li>
`
).join('');
matchList.innerHTML = html;
} else {
matchList.innerHTML = null;
}
}
search.addEventListener('input', () => searchStates(search.value));