Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Hijacking Hacker News with Ember.js
Search
Godfrey Chan
March 03, 2015
Programming
640
3
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Hijacking Hacker News with Ember.js
EmberConf 2015
Godfrey Chan
March 03, 2015
More Decks by Godfrey Chan
See All by Godfrey Chan
Virtual EmberConf 2022: Platform State of the Union
chancancode
0
320
Virtual EmberConf 2021: Platform State of the Union
chancancode
0
250
Virtual EmberConf 2020: Platform State of the Union
chancancode
1
400
Thinking in TypeScript
chancancode
0
320
The Lifecycle of a Rails Request
chancancode
3
15k
Dropping Down To The Metal™ (2018)
chancancode
0
180
Using Skylight to Solve Real-World Performance Problems
chancancode
1
460
Prying Open The Black Box (EmberConf 2018)
chancancode
0
440
Bending The Curve: Putting Rust in Ruby with Helix
chancancode
2
2.9k
Other Decks in Programming
See All in Programming
Turning Architecture into Unit Tests in the AI Era (NSSpain XIV)
steliosf
PRO
1
120
手動確認はもう限界 〜XCUITestでCustom URL Schemeの遷移を起動種別ごとに自動テストする〜 / Testing Custom URL Schemes with XCUITest
otouto
0
370
スマートフォンでモールス信号を送受信する 〜スマートフォンのLEDとカメラで作る光通信の設計と実装〜
atsuki_seo
0
220
TiDB Cloudのカスタムコントローラーによるオートスケール対応
takaidohigasi
0
140
選挙速報を多くのユーザーへ 届ける Live Activities 設計
hamayokokuririn
0
190
AgentCore CLI で進化した AWS での AI エージェントの作り方 : 必要な機能を必要な時に
icoxfog417
PRO
4
410
Omarchy Tokyo やると聞いて UMPC 買ってセットアップしてきた
mtsmfm
0
200
コードレビューのボトルネックを"する側"と"される側"の両面から解消する
yub0n
2
1.3k
iOSDC Japan 2026 - Swiftで作って学ぼう!データベース自作入門
kaseken
2
420
20260914 AIエージェント時代のPlatform Engineering LLM基盤とプロダクトの責務境界線
kanfab1
7
2.3k
ソニーのクラウド共通基盤の変遷とAI時代の開発スタイルに合わせた進化 / The Journey of Sony’s Common Cloud Platform and Its Evolution for AI-Native Development
kenjiyoneyama
0
210
Findy - エンジニア向け会社紹介/Findy Company Deck
findyinc
6
400k
Featured
See All Featured
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
21
1.6k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
230
23k
Why Mistakes Are the Best Teachers: Turning Failure into a Pathway for Growth
auna
0
310
Accessibility Awareness
sabderemane
1
230
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
16k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
1.3k
Ruling the World: When Life Gets Gamed
codingconduct
0
380
Navigating the Design Leadership Dip - Product Design Week Design Leaders+ Conference 2024
apolaine
2
450
How to train your dragon (web standard)
notwaldorf
97
6.8k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
37
6.6k
The Director’s Chair: Orchestrating AI for Truly Effective Learning
tmiket
1
310
brightonSEO & MeasureFest 2025 - Winning Strategies for Black Friday CRO & PPC - Christian Goodrich
cargoodrich
3
860
Transcript
@chancancode Wednesday, 4 March, 15
Wednesday, 4 March, 15
Wednesday, 4 March, 15
BEFORE AFTER image courtesy of TOM DALE “THE FACE OF
OUR NATION” Wednesday, 4 March, 15
Wednesday, 4 March, 15
Wednesday, 4 March, 15
Wednesday, 4 March, 15
Wednesday, 4 March, 15
52 °F Wednesday, 4 March, 15
52 °F 52 °Freedom Wednesday, 4 March, 15
52 °F 52 °Freedom DEGREES OF FREEDOM Wednesday, 4 March,
15
52 °F 52 °Freedom 11 °cDEGREES OF FREEDOM Wednesday, 4
March, 15
52 °F 52 °Freedom 11 °CANADA 11 °cDEGREES OF FREEDOM
Wednesday, 4 March, 15
52 °F 52 °Freedom 11 °CANADA 11 °cDEGREES OF FREEDOM
“It is currently 11 degrees, in canada.” Wednesday, 4 March, 15
var isEmpty = false; var isLoaded = true; Wednesday, 4
March, 15
var isEmpty = false; var isLoaded = true; var emptyEh
= false; var loadedEh = true; Wednesday, 4 March, 15
>> require 'canada' => true >> [].empty_eh? => true >>
[1,2,3].empty_eh? => false Wednesday, 4 March, 15
gem install canada Wednesday, 4 March, 15
alias npm=gem npm install canada Wednesday, 4 March, 15
Wednesday, 4 March, 15
To Rem 3 Terrible Hacks Wednesday, 4 March, 15
To Rem 3 Terrible Hacks LOL Wednesday, 4 March, 15
You Should A Design Pattern ace Wednesday, 4 March, 15
You Should A Design Pattern YASSS ace Wednesday, 4 March,
15
This Slide? What Colors Are Wednesday, 4 March, 15
This Slide? What Colors Are POLL Wednesday, 4 March, 15
Wednesday, 4 March, 15
DS.Adapter Wednesday, 4 March, 15
ADAPTER PATTERN Wednesday, 4 March, 15
Wednesday, 4 March, 15
Wednesday, 4 March, 15
Wednesday, 4 March, 15
Wednesday, 4 March, 15
var CanadianSensor = { getTemperature: function() { // Measures temperature
in °C } }; Wednesday, 4 March, 15
function FreedomMonitor(sensor) { setInterval(function() { // Expects °F if (sensor.readTemperature()
> 100) { ... } }, 1000); }; var CanadianSensor = { getTemperature: function() { // Measures temperature in °C } }; Wednesday, 4 March, 15
function CanadianAdapter(sensor) { this.sensor = sensor; }; CanadianAdapter.prototype = {
readTemperature: function() { return this.sensor.getTemperature() * 1.8 + 32; } }; // Use it! new FreedomMonitor( new CanadianAdapter(CanadianSensor) ); Wednesday, 4 March, 15
DEMO TIME! Wednesday, 4 March, 15
chancancode / hn-reader Wednesday, 4 March, 15
GETTING THE DATA Wednesday, 4 March, 15
Wednesday, 4 March, 15
$.get("/news").then( function(html) { var stories = []; $(html).find("tr .title a").each(
function (_, $link) { stories.push({ title: $link.text(), url: $link.attr('href') }); }); ... return stories; }); Wednesday, 4 March, 15
Ember Data ( DATA STORE ) JSON API ( DATA
SOURCE ) Wednesday, 4 March, 15
Ember Data ( DATA STORE ) HACKER NEWS HTML SCRAPPER
( DATA SOURCE ) Wednesday, 4 March, 15
Ember Data ( DATA STORE ) HACKER NEWS HTML SCRAPPER
( DATA SOURCE ) Wednesday, 4 March, 15
DS.Adapter DS.Serializer Wednesday, 4 March, 15
App.StoryAdapter = DS.Adapter.extend({ findAll(store, type, id) { return $.get("/news"); }
}); App.StorySerializer = DS.Serializer.extend({ extractArray(store, type, payload) { var stories = []; $(payload).find("tr .title a").each( ... ); return stories; } }); Wednesday, 4 March, 15
FIXING THE URLS Wednesday, 4 March, 15
Wednesday, 4 March, 15
/ Wednesday, 4 March, 15
/ /stories/ Wednesday, 4 March, 15
/ /stories/ /stories/9132815/ Wednesday, 4 March, 15
/ /stories/ /stories/9132815/ /stories/9132815/COMMENTS/ Wednesday, 4 March, 15
“IDEAL” URLS /stories /stories?filter=latest /stories/9132815/comments /stories/9132815/comments?highlight=9133317 Hacker News URLS /news
/newest /item?id=9132815 /item?id=9133317 Wednesday, 4 March, 15
Ember ROUTER HACKER NEWS URLS Wednesday, 4 March, 15
Ember ROUTER ( ACTUAL APP STATES ) HACKER NEWS URLS
( SERIALIZED APP STATES ) Wednesday, 4 March, 15
Ember ROUTER ( ACTUAL APP STATES ) HACKER NEWS URLS
( SERIALIZED APP STATES ) Wednesday, 4 March, 15
History LOCATION /stories /stories?filter=latest /stories/9132815/comments /stories/9132815/comments?highlight=9133317 HASH LOCATION #/stories #/stories?filter=latest
#/stories/9132815/comments #/stories/9132815/comments?highlight=9133317 Wednesday, 4 March, 15
Ember.HistoryLocation Ember.HashLocation Wednesday, 4 March, 15
App.HackerNewsLocation = Ember.HistoryLocation.extend({ getURL: function() { if (this._super() === "/news")
{ return "/stories"; } else if (...) { ... } }, formatURL: function( logicalPath ) { if (logicalPath === "/stories") { return "/news"; } else if (...) { ... } } }); App.Router.reopen({ location: 'hacker-news' }); Wednesday, 4 March, 15
PREFERENCES Wednesday, 4 March, 15
Ember ROUTER <p>{{ localStorage.zomg }}</p> LOCAL STORAGE localStorage.getItem(“zomg”) Wednesday, 4
March, 15
LOCAL STORAGE localStorage.getItem(“key”); localStorage.setItem(“key”, value); $(window).on(“storage”, ...); EMBER.OBSERVABLE obj.get(“key”); obj.set(“key”,
value); obj.addObserver( ... ); Wednesday, 4 March, 15
App.LocalStorage = Ember.Object.extend({ init: function() { $(window).on("storage", Ember.run.bind(this, "_onStorageEvent") );
}, unknownProperty: function(key) { return localStorage.getItem(key); }, setUnknownProperty: function(key, value) { localStorage.setItem(key, value); return true; }, _onStorageEvent: function(e) { this.notifyPropertyChange(e.key); }, willDestroy: function() { $(window).off("storage"); } }); Wednesday, 4 March, 15
THE POSSIBILITIES Wednesday, 4 March, 15
HTML <div> <span> <img> Cocoa UIView UITextView UIImageView Wednesday, 4
March, 15
Wednesday, 4 March, 15
COCOA BARS! Wednesday, 4 March, 15
$ cd cocoabars $ git status # On branch master
# # Initial commit # nothing to commit (create/copy files and use "git add" to track) Wednesday, 4 March, 15
@chancancode Wednesday, 4 March, 15
Wednesday, 4 March, 15
Here is the URL you are looking for: https://github.com/chancancode/hn-reader Wednesday,
4 March, 15
A few awesome things didn’t make it to the slides.
I’ll be tweeting, stay tuned. Wednesday, 4 March, 15
I’d like to dedicate this talk to my favourite teacher
and life-mentor, Miss Shirley Ngai. Wednesday, 4 March, 15
Thank you EmberConf team for putting this together! Wednesday, 4
March, 15
And of course, thank you Ember contributors for making this
amazing framework. Wednesday, 4 March, 15
Huge thanks to those who beta tested my app and
tolerated the “dry” runs of my talk. Wednesday, 4 March, 15
And finally, thank YOU for sitting through my first-ever conference
talk and being awesome! Wednesday, 4 March, 15
One more thing. Wednesday, 4 March, 15
<canvas> bars Wednesday, 4 March, 15
Wednesday, 4 March, 15
(Yes, that’s it.) Wednesday, 4 March, 15
Wednesday, 4 March, 15