Photo of Type Ahead API
I am learning with Skillcrush. Please check them out and consider signing up if you're looking to break into tech! Receive $250 off your course by using the link above. Use the coupon code: TWIXMIXY
NOTE: this discount is for Break Into Tech + Get Hired package exclusively. It's the same program I am participating in!
Today's challenge comes from JavaScript30.
I have a migraine today, so I will try to get through today's challenge and explain everything that I'm learning. Do you experience severe headaches or migraines? I'd love to know what you've done or do to help alleviate them or ideally not bring them on to begin with. HMU in the comments!
JavaScript30 - Day 6
All the CSS and HTML are completed for this challenge, so we'll be jumping right into the JS.
We're creating a searchable database. The data is city/state with population information.
The information on the cities was already laid out for us in the script as well.
<script>
const endpoint = 'https://gist.githubusercontent.com/Miserlou/c5cd8364bf9b2420bb29/raw/2bf258763cdddd704f8ffd3ea9a3e81d25e2c6f6/cities.json';
</script>
Our first line of code will be writing an empty array to put our cities into.
const cities = [];
Next we need to fetch our data.
fetch(endpoint)
.then(blob => blob.json())
.then(data => cities.push(...data));
OK. So this immediately became confusing to me. We're using the Arrow Function, which is fine! BUT I'm just not really understanding .then
or blob
really.
I think I understand the cities.push(...data)
is putting the endpoint
data into the cities array, so it's now fetching the cities array. But that's really all I got from that so far.
Here's what I have so far...
<script>
const endpoint = 'https://gist.githubusercontent.com/Miserlou/c5cd8364bf9b2420bb29/raw/2bf258763cdddd704f8ffd3ea9a3e81d25e2c6f6/cities.json';
const cities = [];
fetch(endpoint)
.then(blob => blob.json())
.then(data => cities.push(...data));
console.log(cities);
</script>
And when I ran my cities
console log it did come back with all of the endpoint
data. So that's why I think I understand that aspect of it.
Now we are going to create functions that will call on the array so that when typing in the search bar, it will pull back the data we are requesting.
function findMatches(wordToMatch, cities) {
return cities.filter(place => {
// here we need to figure out if the city of state matches what was searched
const regex = new RegExp(wordToMatch, 'gi');
return place.city.match(regex) || place.state.match(regex)
});
}
This function covers a lot. So we are creating findMatches
with the parameters being wordToMatch
and our already created variable cities
.
We return cities and of course we want to filter it, because we are looking to have it search (aka filter) on the wide array of cities listed in our json file.
The part where it gets tricky for me is the variable within the function, regex. I looked up RegExp and it means a regular expression relating to matching data, so that makes some sense. Then the parameters for it are the wordToMatch and "gi". gi
means global and insensitive (not case sensitive).
Finally we return the data using the match with the parameter of the new regex
variable. Returning place for both the city or the state.
Note I haven't been able to get this to validate in my console log, so I may have a bug in my code at this point. I'm going to keep pushing forward to see if I can get it working later.
Next we move on to the display function.
function displayMatches() {
console.log(this.value);
}
This did nothing in my console, but I also didn't see it do anything in the instructors console.
We are now moving on to pulling in classes from the HTML to begin manipulating what's seen on the screen.
const searchInput = document.querySelector('.search');
const suggestions = document.querySelector('.suggestions');
Now that we have those tied in we can create event listeners.
searchInput.addEventListener('change', displayMatches);
The data I am typing in the search bar is now displaying in the console log.
We added another event listener, so the search works for each letter entered.
searchInput.addEventListener('keyup', displayMatches);
Returning to the displayMatches
function, we created a variable that pulls in the findMatches
variable, so now when typing into the search bar, the console will pull back matching values.
OK. The next step is all about the pulled back data and how it's displaying.
function displayMatches() {
// console.log(this.value);
const matchArray = findMatches(this.value, cities);
// console.log(matchArray);
const html = matchArray.map(place => {
return `
<li>
<span class="name">${place.city}, ${place.state}</span>
<span class="population">${place.population}</span>
</li>
`;
}).join('');
suggestions.innerHTML = html;
}
We created a new variable html
which we are mapping over the matchArray
, so we can return some HTML which displays the city, state and population. Since it's an array we needed to add .join at the end. Don't fully understand that, but I'm sure I'll learn some day.
Then we tie in the suggestions
to manipulate our HTML with the new html
variable written.
Nearly there, next we want to highlight the text typed into the search bar.
function displayMatches() {
// console.log(this.value);
const matchArray = findMatches(this.value, cities);
// console.log(matchArray);
const html = matchArray.map(place => {
const regex = new RegExp(this.value, 'gi');
const cityName = place.city.replace(regex, `<span class="hl">${this.value}</span>`);
const stateName = place.state.replace(regex, `<span class="hl">${this.value}</span>`);
return `
<li>
<span class="name">${cityName}, ${stateName}</span>
<span class="population">${place.population}</span>
</li>
`;
}).join('');
suggestions.innerHTML = html;
}
To do this we are using .replace
, which isn't something I've utilized before. Using the weird regex thing again. What it's doing is basically finding the regex
and replacing it with the new highlighter span we created.
Finally, we need to add in commas for the population. Basically the instructor just copies/pastes this one in.
function numberWithCommas(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
};
Still needed to update the displayMatches function so the display of the population was properly updated.
<span class="population">${numberWithCommas(place.population)}</span>
That's it! Of course I want to update the appearance a bit, but this is great if I ever want to build a search engine. I feel like I could definitely use this as a starting place.
Top comments (0)