const html = (content) => { let template = document.createElement("template"); template.innerHTML = content; return template.content }; class NewsSummary extends HTMLElement { constructor() { super(); this.cache = true; this.state = {}; } async read(part, id) { let hn = "https://hacker-news.firebaseio.com/v0"; switch(part) { case "list": return await fetch(`${hn}/topstories.json`).then(r => r.json()).then(r => r); case "details": return await fetch(`${hn}/item/${id}.json`).then(r => r.json()).then(r => r); default: return {} } } /** * Returns a value or false * * useful for truthy expressions where objects or arrays are defined, but empty * * @param {Any} val */ _exists(val) { // console.log('typeof', val, typeof val); if(typeof val !== 'object' || val === null) { return !!val ? val : false; } else { if(typeof val === "object") { if(val.length !== 'undefined') { return !!val.length ? val : false; } else { return (Object.getOwnPropertyNames(val).length > 0) ? val : false; } } } } /** * Local Storage Helper */ _store() { return { get: (key) => { return this._exists(JSON.parse(window.localStorage.getItem(key))); }, set: (key, val) => { return this._exists(window.localStorage.setItem(key, JSON.stringify(val))); } } } async connectedCallback() { console.log('connected'); // get identifiers list if(this.cache) { console.log('cache enabled...'); if(this._store().get("list")) { console.log('found in cache...'); this.state.list = this._store().get("list"); } else { console.log('building cache...'); let list = await this.read("list"); this.state.list = list; this._store().set("list", list); } } // get details from idenifiers list if (this.cache) { console.log('cache enabled...'); if (this._store().get("details")) { console.log('found in cache...'); this.state.details = this._store().get("details"); } else { console.log('building cache...'); this.state.details = []; for (let i =0; i < 15; i++) { let item = await this.read("details", this.state.list[i]); this.state.details.push(item); } this._store().set("details", this.state.details); } console.log('...done'); } this._render(); } // _template() { // return html` //
//
${item.title}
//
[ hype: ${item.score} | topic: ${item.type} | source: ${item.by} | ${item.kids.length} comments ]
//
// `; // } _render() { this.innerHTML = ` ${this.state.details.map(item => `
${item.title}
[ hype: ${item.score} | topic: ${item.type} | source: ${item.by} | ${(item.kids || []).length} comments ]
`).join('')} `; } } customElements.define('news-summary', NewsSummary);