Skip to content

Commit bcbab53

Browse files
committed
Project 6 complete with more strict tsc flags
1 parent df26f0a commit bcbab53

File tree

4 files changed

+111
-6
lines changed

4 files changed

+111
-6
lines changed

06 - Type Ahead/index-START.html

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
<!DOCTYPE html>
22
<html lang="en">
3+
34
<head>
45
<meta charset="UTF-8">
56
<title>Type Ahead 👀</title>
67
<link rel="stylesheet" href="style.css">
78
</head>
9+
810
<body>
911

1012
<form class="search-form">
@@ -14,9 +16,7 @@
1416
<li>or a state</li>
1517
</ul>
1618
</form>
17-
<script>
18-
const endpoint = 'https://gist.githubusercontent.com/Miserlou/c5cd8364bf9b2420bb29/raw/2bf258763cdddd704f8ffd3ea9a3e81d25e2c6f6/cities.json';
19-
20-
</script>
19+
<script src="typescripts.js"></script>
2120
</body>
22-
</html>
21+
22+
</html>

06 - Type Ahead/typescripts.js

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
var endpoint = 'https://gist.githubusercontent.com/Miserlou/c5cd8364bf9b2420bb29/raw/2bf258763cdddd704f8ffd3ea9a3e81d25e2c6f6/cities.json';
2+
var cities = [];
3+
fetch(endpoint)
4+
.then(function (blob) { return blob.json(); })
5+
.then(function (data) { return cities.push.apply(cities, data); });
6+
function findMatches(wordToMatch, cities) {
7+
return cities.filter(function (place) {
8+
var regexp = new RegExp(wordToMatch, 'gi');
9+
return place.city.match(regexp) || place.state.match(regexp);
10+
});
11+
}
12+
function numberWithCommas(x) {
13+
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
14+
}
15+
function displayMatches() {
16+
var _this = this;
17+
var matchArray = findMatches(this.value, cities);
18+
var html = matchArray.map(function (place) {
19+
var regexp = new RegExp(_this.value, 'gi');
20+
var cityName = place.city.replace(regexp, "<span class=\"hl\">" + _this.value + "</span>");
21+
var stateName = place.state.replace(regexp, "<span class=\"hl\">" + _this.value + "</span>");
22+
return ("\n <li>\n <span class=\"name\">" + cityName + ", " + stateName + "</span>\n <span class=\"population\">" + numberWithCommas(place.population) + "</span>\n </li>\n ");
23+
}).join('');
24+
if (suggestions) {
25+
suggestions.innerHTML = html;
26+
}
27+
else {
28+
throw new Error('Suggestions block not found');
29+
}
30+
}
31+
var searchInput = document.querySelector('.search');
32+
var suggestions = document.querySelector('.suggestions');
33+
if (searchInput) {
34+
searchInput.addEventListener('change', displayMatches);
35+
searchInput.addEventListener('keyup', displayMatches);
36+
}
37+
else {
38+
throw new Error('Search input not found');
39+
}

06 - Type Ahead/typescripts.ts

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/**
2+
* JavaScript30 by Wes Bos, https://javascript30.com/
3+
* TypeScript implementation by Will Wager
4+
* Project: Type Ahead
5+
* Concepts: AJAX, Fetch API
6+
* Key takeaways: Get the data first, then worry about displaying it.
7+
* Sidenotes:
8+
* Fetch API uses Promises.
9+
* I've no idea how that comma adding regexp works...
10+
*/
11+
12+
interface City {
13+
city: string;
14+
state: string;
15+
population: number;
16+
}
17+
18+
const endpoint = 'https://gist.githubusercontent.com/Miserlou/c5cd8364bf9b2420bb29/raw/2bf258763cdddd704f8ffd3ea9a3e81d25e2c6f6/cities.json';
19+
20+
const cities: City[] = [];
21+
22+
fetch(endpoint)
23+
.then(blob => blob.json())
24+
.then(data => cities.push(...(data as City[])));
25+
26+
function findMatches(wordToMatch: string, cities: City[]) {
27+
return cities.filter(place => {
28+
const regexp = new RegExp(wordToMatch, 'gi');
29+
return place.city.match(regexp) || place.state.match(regexp);
30+
});
31+
}
32+
33+
function numberWithCommas(x: number) {
34+
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
35+
}
36+
37+
function displayMatches() {
38+
const matchArray = findMatches(this.value, cities);
39+
const html = matchArray.map(place => {
40+
const regexp = new RegExp(this.value, 'gi');
41+
const cityName = place.city.replace(regexp, `<span class="hl">${this.value}</span>`);
42+
const stateName = place.state.replace(regexp, `<span class="hl">${this.value}</span>`);
43+
return (`
44+
<li>
45+
<span class="name">${cityName}, ${stateName}</span>
46+
<span class="population">${numberWithCommas(place.population)}</span>
47+
</li>
48+
`);
49+
}).join('');
50+
51+
if (suggestions) {
52+
suggestions.innerHTML = html;
53+
} else {
54+
throw new Error('Suggestions block not found');
55+
}
56+
}
57+
58+
const searchInput = document.querySelector('.search');
59+
const suggestions = document.querySelector('.suggestions');
60+
61+
if (searchInput) {
62+
searchInput.addEventListener('change', displayMatches);
63+
searchInput.addEventListener('keyup', displayMatches);
64+
} else {
65+
throw new Error('Search input not found');
66+
}

readme.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Run them yourself from a VS Code container!
77
* Open in vscode and run `Remote Containers: Reopen in Container` from the command palette.
88
* Build each TypeScript file with `tsc typescripts.ts` from each project's folder.
99
* All html files have been adjusted to look for typescripts.js.
10-
* I use the options `--target es5 --removeComments` in my js builds.
10+
* Starting at project 6, I use the options `--removeComments --strictNullChecks --noImplicitAny --target es5 ` in my js builds.
1111
* Press ALT + L, ALT + O to start the Live Server extension and access the html files at http://localhost:5500 + the relative path.
1212
* For example, to open the first project, go to (replace spaces with '20%' if your browser complains): `http://localhost:5500/01%20-%20JavaScript%20Drum%20Kit/index-START.html`
1313

0 commit comments

Comments
 (0)