Skip to content

Instantly share code, notes, and snippets.

@jcpst
Last active January 5, 2018 07:35
Show Gist options
  • Save jcpst/cf536e275e9d829a2e160a7593eb40c7 to your computer and use it in GitHub Desktop.
Save jcpst/cf536e275e9d829a2e160a7593eb40c7 to your computer and use it in GitHub Desktop.
SFA (Single File App) - retrieve countries
<html><head><!--
This is a single file app, built with hyperapp.
It uses REST Countries for a data source.
Web apps do not have to be huge, complex, and have build configurations.
--><style>
/* ==========================================================================
/* Styles.
/* ========================================================================*/
table th,table td {
padding: .5em;
text-align: left;
}
table tbody > :nth-child(2n-1) {
background: #ddd;
}
</style></head><body>
<script src="https://unpkg.com/[email protected]"></script>
<script src="https://unpkg.com/@hyperapp/[email protected]"></script>
<script>
const { h, app } = hyperapp
const { main, h1, h3, button, table, thead, tbody, tr, th, td, img, a } = html
// ==========================================================================
// State.
// ==========================================================================
const state = {
isFetching: false,
countries: [{
name: '',
capital: '',
population: 0,
latlng: [0,0],
flag: ''
}]
}
// ==========================================================================
// Actions.
// ==========================================================================
const actions = {
getCountries: () => async (state, actions) => {
actions.toggleFetching(true)
const response = await fetch('https://restcountries.eu/rest/v2/all')
const countries = await response.json()
actions.setCountries(countries)
actions.toggleFetching(false)
},
toggleFetching: isFetching => ({ isFetching }),
setCountries: countries => ({ countries })
}
// ==========================================================================
// Components.
// ==========================================================================
const Flag = ({ lat, lon, flag }, c) =>
a({ href: `http://www.openstreetmap.org/?mlat=${lat}&mlon=${lon}&zoom=6`, target: '_blank' }, [
img({ src: flag, width: 45 })
])
const CountryTableRow = ({ country }, c) =>
tr({}, [
td({}, [
Flag({
class: 'flag',
lat: country.latlng[0],
lon: country.latlng[1],
flag: country.flag
}),
country.name
]),
td({}, country.capital),
// regex from here: https://stackoverflow.com/a/2901298/3957261
td({}, country.population.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","))
])
// ==========================================================================
// View.
// ==========================================================================
const view = (state, actions) =>
main({}, [
h1({}, 'List of Countries'),
button({ onclick: actions.getCountries }, 'Get Countries'),
state.isFetching
? h3('fetching...')
: table({}, [
thead({}, [
tr({}, [
th({}, 'name'),
th({}, 'capital'),
th({}, 'population')
])
]),
tbody({}, [
state.countries.map(country => CountryTableRow({ country }))
])
])
])
// ==========================================================================
// Initialization.
// ==========================================================================
app(state, actions, view, document.body)
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment