Skip to content

Instantly share code, notes, and snippets.

@jellehak
Last active April 14, 2021 10:15
Show Gist options
  • Save jellehak/938cd9ff7f76835793ed6a5c66b37f85 to your computer and use it in GitHub Desktop.
Save jellehak/938cd9ff7f76835793ed6a5c66b37f85 to your computer and use it in GitHub Desktop.
App as library example
<!DOCTYPE html>
<html>
<head>
<title>TODO app</title>
</head>
<body>
<div id="app1">
loading...
</div>
<div id="app2">
loading...
</div>
<script type="module">
// import { createApp } from "./app.js"
// Sugar
function c(name = '', props, children = []) {
const el = document.createElement(name)
Object.assign(el, props)
children.forEach(c => el.appendChild(c));
return el
}
function createApp(config = {}) {
const { service } = config
return {
async $mount(id) {
const root = document.getElementById(id)
const state = {
joke: {}
}
root.innerHTML = 'loading...'
// Call service
state.joke = await service.getAll()
function render(_state = state) {
const setButton = c('button', {
innerHTML: 'Set joke',
onclick() {
const joke = { "id": 363, "type": "general", "setup": "Why do mathematicians hate the U.S.?", "punchline": "Because it's indivisible." }
state.joke = joke
service.saveAll(state)
render()
}
});
const clearButton = c('button', {
innerHTML: 'Clear joke',
onclick() {
console.log('clear')
const joke = null
state.joke = joke
console.log(state)
service.saveAll(state)
render()
}
});
const app = c('div', {}, [
c('h1', {innerHTML: config.title }),
c('div', {
innerHTML: JSON.stringify(_state.joke, null, 2)
}), setButton, clearButton])
root.replaceChildren(app);
}
render()
}
}
}
class LocalService {
constructor({ key = 'joke' } = {}) {
this.key = key
}
async getAll() {
const resp = localStorage.getItem(this.key)
return JSON.parse(resp)
}
async saveAll(body) {
localStorage.setItem(this.key, JSON.stringify(body))
}
}
class ApiService {
constructor({ server = '/api' } = {}) {
this.server = server
}
async getAll() {
return fetch(this.server).then(elem => elem.json())
}
async saveAll(body = {}) {
console.warn('Joke Api is read only')
// return fetch(this.server, {
// method: 'POST',
// body: JSON.stringify(body)
// }).then(elem => elem.json())
}
}
const commonConfig = {
title: 'Joke App'
}
// Local
createApp({
...commonConfig,
title: 'Joke App (local)',
service: new LocalService()
}).$mount('app1')
// Remote
createApp({
...commonConfig,
service: new ApiService({ server: 'https://official-joke-api.appspot.com/random_joke' })
}).$mount('app2')
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment