Building a Single Page Application using Ember.js ... for fun and profit
-
Upload
ben-limmer -
Category
Technology
-
view
1.257 -
download
0
Transcript of Building a Single Page Application using Ember.js ... for fun and profit
![Page 1: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/1.jpg)
Building a Single Page App with Ember.js
…for fun and profit!
![Page 2: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/2.jpg)
largest free entrepreneurial event of its kind in North America
![Page 3: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/3.jpg)
yay, sponsors!
![Page 4: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/4.jpg)
Ben Limmer! blimmer " @l1m5 # [email protected]$ ember.party
![Page 5: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/5.jpg)
conceptual
![Page 6: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/6.jpg)
Ron White! ronco " @ronco1337
![Page 7: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/7.jpg)
live coding
![Page 8: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/8.jpg)
![Page 9: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/9.jpg)
![Page 10: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/10.jpg)
$2cash back
![Page 11: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/11.jpg)
$5cash back
![Page 12: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/12.jpg)
$5cash back
$10cash back
$10cash back
![Page 13: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/13.jpg)
![Page 14: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/14.jpg)
we need a website
![Page 15: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/15.jpg)
ok - what does it do?
![Page 16: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/16.jpg)
it’s simple, really
![Page 17: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/17.jpg)
show rebates
it needs to
allow registration
allow account mgmt
provide cash out
explain how it worksshow where it works
…
build a shopping list
be location aware
track all the things
![Page 18: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/18.jpg)
![Page 19: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/19.jpg)
![Page 20: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/20.jpg)
how do we build it?
![Page 21: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/21.jpg)
server-rendered?
![Page 22: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/22.jpg)
ibotta.com
![Page 23: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/23.jpg)
ibotta.com
![Page 24: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/24.jpg)
ibotta.com
html, js, css
![Page 25: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/25.jpg)
ibotta.com
*click*
![Page 26: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/26.jpg)
html, js, css
ibotta.com
![Page 27: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/27.jpg)
ibotta.com
![Page 28: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/28.jpg)
client rendered? (single page app)
![Page 29: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/29.jpg)
ibotta.com
![Page 30: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/30.jpg)
ibotta.com
![Page 31: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/31.jpg)
ibotta.com
html, js, css
![Page 32: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/32.jpg)
ibotta.com
*click*
![Page 33: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/33.jpg)
ibotta.com
json
![Page 34: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/34.jpg)
ibotta.com
*click*
![Page 35: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/35.jpg)
ibotta.com
*click*
![Page 36: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/36.jpg)
ibotta.com
![Page 37: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/37.jpg)
ibotta.com
![Page 38: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/38.jpg)
single page apps are not always the best choice.
![Page 39: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/39.jpg)
pre-render challenges (seo, social share)overkill for simple sites
some duplication of backend data
requires (building) an API
![Page 40: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/40.jpg)
but you’re here
![Page 41: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/41.jpg)
single page app frameworks
![Page 42: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/42.jpg)
single page app frameworks
![Page 43: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/43.jpg)
single page app frameworks
![Page 44: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/44.jpg)
single page app frameworks
![Page 45: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/45.jpg)
single page app frameworks
![Page 46: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/46.jpg)
single page app frameworks
![Page 47: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/47.jpg)
very un-opinionated
very opinionated
![Page 48: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/48.jpg)
so why did we go with Ember @ Ibotta?
![Page 49: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/49.jpg)
![Page 50: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/50.jpg)
¯\_(ツ)_/¯
![Page 51: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/51.jpg)
convention over configuration
![Page 52: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/52.jpg)
– Ruby on Rails Guides
“conventions will speed up development, keep your code concise and readable and - most
important - these conventions allow you an easy navigation inside your application.”
https://en.wikibooks.org/wiki/Ruby_on_Rails/Getting_Started/Convention_Over_Configuration* emphasis mine
![Page 53: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/53.jpg)
structure of an ember appapp ├── components ├── controllers ├── helpers ├── models ├── routes ├── styles └── templates └── components
tests ├── helpers ├── integration │ └── components └── unit
![Page 54: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/54.jpg)
who cares? it’s just a framework…
![Page 55: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/55.jpg)
*Icons made Freepik from www.flaticon.com is licensed by CC BY 3.0
![Page 56: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/56.jpg)
*Icons made Freepik from www.flaticon.com is licensed by CC BY 3.0
![Page 57: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/57.jpg)
*Icons made Freepik from www.flaticon.com is licensed by CC BY 3.0
![Page 58: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/58.jpg)
*Icons made Freepik from www.flaticon.com is licensed by CC BY 3.0
![Page 59: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/59.jpg)
knowledge in the head vs.
knowledge in the world
adapted from concepts in Don Norman’s The Design of Everyday Things
![Page 60: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/60.jpg)
*Icons made Freepik from www.flaticon.com is licensed by CC BY 3.0
used by many
used by few
![Page 61: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/61.jpg)
*Icons made Freepik from www.flaticon.com is licensed by CC BY 3.0
used by few
used by many
more knowledge in the head
![Page 62: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/62.jpg)
*Icons made Freepik from www.flaticon.com is licensed by CC BY 3.0
used by few
used by many
more knowledge in the head
more knowledge in the world
![Page 63: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/63.jpg)
*Icons made Freepik from www.flaticon.com is licensed by CC BY 3.0
used by few
used by many
more knowledge in the head
more knowledge in the world
![Page 64: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/64.jpg)
*Icons made Freepik from www.flaticon.com is licensed by CC BY 3.0
used by few
used by many
more knowledge in the head
more knowledge in the world
![Page 65: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/65.jpg)
![Page 66: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/66.jpg)
} how it works
![Page 67: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/67.jpg)
![Page 68: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/68.jpg)
how it works
![Page 69: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/69.jpg)
how it works
![Page 70: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/70.jpg)
how it works
![Page 71: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/71.jpg)
?
![Page 72: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/72.jpg)
![Page 73: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/73.jpg)
} how it works
![Page 74: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/74.jpg)
} how it works
![Page 75: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/75.jpg)
best practices are established
![Page 76: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/76.jpg)
testing
routing data definition
validation i18n
builds deployment
dev tools
upgrade paths
![Page 77: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/77.jpg)
“there’s an add-on for that”
![Page 78: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/78.jpg)
automated testing
out-of-the-box support w/ qunit and phantom
![Page 79: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/79.jpg)
modern language features
out-of-the-box support for ES6/ES2015++ with
Babel.js
![Page 80: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/80.jpg)
✓Array comprehensions ✓Arrow functions ✓Async functions ✓Async generator functions ✓Classes ✓Class properties ✓Computed property names ✓Constants ✓Decorators ✓Default parameters ✓Destructuring ✓Exponentiation operator ✓For-of ✓Function bind
✓Generators ✓Generator comprehensions ✓Let scoping ✓Modules ✓Module export extensions ✓Object rest/spread ✓Property method assignment ✓Property name shorthand ✓Rest parameters ✓React ✓Spread ✓Template literals ✓Type annotations ✓Unicode regex
![Page 81: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/81.jpg)
no morevar self = this;
![Page 82: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/82.jpg)
design frameworks
plug-and-play support for the most popular design
frameworks and preprocessors
![Page 83: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/83.jpg)
i18nember i18n
您好
Здравствуйте!
hello
bonjour
hola
![Page 84: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/84.jpg)
“there’s an add-on for that”
![Page 85: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/85.jpg)
“there’s (not) an add-on for that”
![Page 86: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/86.jpg)
ember add-on
![Page 87: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/87.jpg)
thriving community
![Page 88: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/88.jpg)
![Page 89: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/89.jpg)
![Page 90: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/90.jpg)
![Page 91: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/91.jpg)
3000 members (and growing)
![Page 92: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/92.jpg)
400 members (and growing)
Denver Devs
![Page 93: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/93.jpg)
DenverDevs.org
![Page 94: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/94.jpg)
![Page 95: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/95.jpg)
meetup.com/ Ember-js-Denver
![Page 96: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/96.jpg)
![Page 97: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/97.jpg)
ember @ ibotta
![Page 98: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/98.jpg)
0 to prod in two months
![Page 99: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/99.jpg)
> 2x traffic
![Page 100: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/100.jpg)
![Page 101: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/101.jpg)
![Page 102: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/102.jpg)
![Page 103: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/103.jpg)
internal ember apps
![Page 104: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/104.jpg)
let’s build something.
![Page 105: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/105.jpg)
…but first initial questions?
![Page 106: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/106.jpg)
let’s build something.
![Page 107: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/107.jpg)
Our App
![Page 108: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/108.jpg)
Our App
![Page 109: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/109.jpg)
$ ember new bbs
![Page 110: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/110.jpg)
demo
![Page 111: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/111.jpg)
structure of our appapp ├── components ├── controllers ├── helpers ├── models ├── routes ├── styles └── templates └── components
tests ├── helpers ├── integration │ └── components └── unit
![Page 112: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/112.jpg)
./app/templates/application.hbs
1 <h2 id="title">Welcome to Ember</h2> 2 3 {{outlet}}
Live reload demo here.
Hello Denver!
![Page 113: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/113.jpg)
demo
![Page 114: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/114.jpg)
$ ember install ember-cli-materialize$ ember install ember-i18n
![Page 115: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/115.jpg)
demo
![Page 116: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/116.jpg)
I18n
1 <!-- ./app/templates/index.hbs --> 2 <div class="home-feature"> 3 <div class="feature-content"> 4 <h1>{{t 'index.headline'}}</h1> 5 <h3>{{t 'index.subTitle'}}</h3> 6 </div> 7 </div>
1 // ./app/locales/en/translations.js 2 export default { 3 'index': { 4 'headline': 'Frozen Bananas!', 5 'subTitle': 'Coming Soon' 6 } 7 };
![Page 117: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/117.jpg)
I18n
3 <div class="feature-content"> 4 <h1>{{t 'index.headline'}}</h1> 5 <h3>{{t 'index.subTitle'}}</h3> 6 </div>
![Page 118: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/118.jpg)
I18n
1 <!-- ./app/templates/index.hbs --> 2 <div class="home-feature"> 3 <div class="feature-content"> 4 <h1>{{t 'index.headline'}}</h1> 5 <h3>{{t 'index.subTitle'}}</h3> 6 </div> 7 </div>
1 // ./app/locales/en/translations.js 2 export default { 3 'index': { 4 'headline': 'Frozen Bananas!', 5 'subTitle': 'Coming Soon' 6 } 7 };
![Page 119: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/119.jpg)
I18n
1 // ./app/locales/en/translations.js 2 export default { 3 'index': { 4 'headline': 'Frozen Bananas!', 5 'subTitle': 'Coming Soon' 6 } 7 };
![Page 120: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/120.jpg)
$ ember generateacceptance-test index
![Page 121: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/121.jpg)
./tests/acceptance/index-test.js
1 // ... 2 3 test('visiting /index', function(assert) { 4 assert.expect(3); 5 visit('/'); 6 7 andThen(function() { 8 assert.equal(currentURL(), '/'); 9 let headline = find('.home-feature h1'); 10 assert.equal(headline.length, 1); 11 assert.equal(headline.text(), 'Frozen Bananas!'); 12 }); 13 }); Promise explainer Here?
![Page 122: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/122.jpg)
./tests/acceptance/index-test.js
5 visit('/');
![Page 123: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/123.jpg)
./tests/acceptance/index-test.js
1 // ... 2 3 test('visiting /index', function(assert) { 4 assert.expect(3); 5 visit('/'); 6 7 andThen(function() { 8 assert.equal(currentURL(), '/'); 9 let headline = find('.home-feature h1'); 10 assert.equal(headline.length, 1); 11 assert.equal(headline.text(), 'Frozen Bananas!'); 12 }); 13 });
![Page 124: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/124.jpg)
./tests/acceptance/index-test.js
7 andThen(function() { 8 assert.equal(currentURL(), '/'); 9 let headline = find('.home-feature h1'); 10 assert.equal(headline.length, 1); 11 assert.equal(headline.text(), 'Frozen Bananas!'); 12 });
![Page 125: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/125.jpg)
√ ok 1 PhantomJS 2.0 - Acceptance | index: visiting /index
![Page 126: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/126.jpg)
Our App
![Page 127: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/127.jpg)
Our App
![Page 128: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/128.jpg)
$ ember generate route about
![Page 129: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/129.jpg)
./app/router.js
1 import Ember from 'ember'; 2 import config from './config/environment'; 3 4 var Router = Ember.Router.extend({ 5 location: config.locationType 6 }); 7 8 Router.map(function() { 9 this.route('about'); 10 }); 11 12 export default Router;
![Page 130: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/130.jpg)
./app/router.js
8 Router.map(function() { 9 this.route('about'); 10 });
![Page 131: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/131.jpg)
./app/templates/about.hbs
1 <div class="container"> 2 {{#md-card 3 title=(t 'about.title') 4 class="teal" 5 titleClass="white-text" 6 bodyClass="white-text" 7 id="address-card"}} 8 {{#md-card-content class="white-text"}} 9 <p>{{t 'about.number'}}</p> 10 <p>{{t 'about.street'}}</p> 11 {{/md-card-content}} 12 {{/md-card}} 13 </div>
![Page 132: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/132.jpg)
./app/templates/about.hbs
2 {{#md-card 3 title=(t 'about.title') 4 class="teal" 5 titleClass="white-text" 6 bodyClass="white-text" 7 id="address-card"}} 12 {{/md-card}}
![Page 133: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/133.jpg)
./app/templates/about.hbs
1 <div class="container"> 2 {{#md-card 3 title=(t 'about.title') 4 class="teal" 5 titleClass="white-text" 6 bodyClass="white-text" 7 id="address-card"}} 8 {{#md-card-content class="white-text"}} 9 <p>{{t 'about.number'}}</p> 10 <p>{{t 'about.street'}}</p> 11 {{/md-card-content}} 12 {{/md-card}} 13 </div>
![Page 134: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/134.jpg)
./app/templates/about.hbs
8 {{#md-card-content class="white-text"}} 9 <p>{{t 'about.number'}}</p> 10 <p>{{t 'about.street'}}</p> 11 {{/md-card-content}}
![Page 135: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/135.jpg)
./app/templates/index.hbs
1 <div class="home-feature"> 2 <div class="feature-content"> 3 <h1>{{t 'index.headline'}}</h1> 4 <h3>{{t 'index.subTitle'}}</h3> 5 <div class="about-link"> 6 {{#link-to 'about'}} 7 <img src="/images/banana_grabber.png"> 8 {{/link-to}} 9 </div> 10 </div> 11 </div>
![Page 136: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/136.jpg)
./app/templates/index.hbs
5 <div class="about-link"> 6 {{#link-to 'about'}} 7 <img src="/images/banana_grabber.png"> 8 {{/link-to}} 9 </div>
![Page 137: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/137.jpg)
demo
![Page 138: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/138.jpg)
$ ember generateacceptance-test about
![Page 139: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/139.jpg)
./tests/acceptance/about-test.js
1 // ... 2 3 test('visiting /about from index', function(assert) { 4 visit('/'); 5 click('.about-link img'); 6 7 andThen(function() { 8 assert.equal(currentURL(), '/about'); 9 }); 10 });
![Page 140: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/140.jpg)
√ ok 1 PhantomJS 2.0 - Acceptance | about: visiting /about from index
![Page 141: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/141.jpg)
![Page 142: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/142.jpg)
$ ember generatemodel company-address
![Page 143: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/143.jpg)
./app/models/company-address.js
1 import DS from 'ember-data'; 2 3 export default DS.Model.extend({ 4 name: DS.attr('string'), 5 street1: DS.attr('string'), 6 street2: DS.attr('string'), 7 city: DS.attr('string'), 8 state: DS.attr('string'), 9 zip: DS.attr('string') //string not number 10 });
![Page 144: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/144.jpg)
./app/models/company-address.js
4 name: DS.attr('string'), 5 street1: DS.attr('string'), 6 street2: DS.attr('string'), 7 city: DS.attr('string'), 8 state: DS.attr('string'), 9 zip: DS.attr('string') //string not number
![Page 145: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/145.jpg)
./app/routes/about.js
1 import Ember from 'ember'; 2 3 export default Ember.Route.extend({ 4 model() { 5 return this.get('store').findAll('company-address'); 6 } 7 });
![Page 146: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/146.jpg)
Promises
![Page 147: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/147.jpg)
Objects not Callbacks
Complete or Not
![Page 148: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/148.jpg)
Chainable
![Page 149: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/149.jpg)
Traditional async
1 asyncCall1(function() { 2 asyncCall2(function() { 3 asyncCall3(function() { 4 asyncCall4(function() { 5 asyncCall5(function() { 6 finalCall(); 7 }); 8 }); 9 }); 10 }); 11 });
![Page 150: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/150.jpg)
Chained Promises
1 asyncCall1() 2 .then(asyncCall2) 3 .then(asyncCall3) 4 .then(asyncCall4) 5 .then(asyncCall5) 6 .then(finalCall);
![Page 151: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/151.jpg)
Chained Promises
1 asyncCall1() 2 .then(asyncCall2) 3 .then(asyncCall3) 4 .then(asyncCall4) 5 .then(asyncCall5) 6 .then(finalCall) 7 .catch(errorHandler);
![Page 152: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/152.jpg)
Deferred Interest
![Page 153: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/153.jpg)
./app/routes/about.js
4 model() { 5 return this.get('store').findAll('company-address'); 6 }
![Page 154: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/154.jpg)
.then(the-template)
![Page 155: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/155.jpg)
./app/templates/about.hbs
1 <div class="container"> 2 {{#md-card 3 title=model.lastObject.name 4 class="teal" 5 titleClass="white-text" 6 bodyClass="white-text" 7 id="address-card"}} 8 {{#md-card-content class="white-text"}} 9 <p>{{model.lastObject.street1}}</p> 10 <p>{{model.lastObject.street2}}</p> 11 <p> 12 {{model.lastObject.city}}, {{model.lastObject.state}} 13 {{model.lastObject.zip}} 14 </p> 15 {{/md-card-content}} 16 {{/md-card}} 17 </div>
Demo, show error page
![Page 156: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/156.jpg)
./app/templates/about.hbs
9 <p>{{model.lastObject.street1}}</p> 10 <p>{{model.lastObject.street2}}</p> 11 <p> 12 {{model.lastObject.city}}, {{model.lastObject.state}} 13 {{model.lastObject.zip}} 14 </p>
Demo, show error page
![Page 157: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/157.jpg)
demo
![Page 158: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/158.jpg)
./app/templates/error.hbs
1 <div class="error-page"> 2 <h1>Ooops!</h1> 3 {{shrug-guy}} 4 </div>
![Page 159: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/159.jpg)
./app/templates/error.hbs
3 {{shrug-guy}}
![Page 160: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/160.jpg)
./app/templates/error.hbs
¯\_(ツ)_/¯
![Page 161: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/161.jpg)
GobServer Engineer
![Page 162: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/162.jpg)
$ ember install ember-cli-mirage
![Page 163: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/163.jpg)
$ ember generate fixture company-addresses
![Page 164: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/164.jpg)
./app/mirage/fixtures/company-addresses.js
1 export default [ 2 { 3 id: 1, 4 name: 'Bluth\'s Banana Stand', 5 street1: 'In a Van', 6 street2: 'Down by the river', 7 city: 'Denver', 8 state: 'CO', 9 zip: 80202 10 } 11 ];
![Page 165: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/165.jpg)
./app/mirage/config.js
1 export default function() { 2 3 this.get('/companyAddresses', 'company-addresses'); 4 5 }
![Page 166: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/166.jpg)
./app/mirage/config.js
3 this.get('/companyAddresses', 'company-addresses');
![Page 167: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/167.jpg)
demo
![Page 168: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/168.jpg)
./app/mirage/config.js
1 export default function() { 2 this.timing = 2000; 3 4 this.get('/companyAddresses', 'company-addresses'); 5 6 }
![Page 169: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/169.jpg)
./app/mirage/config.js
2 this.timing = 2000;
![Page 170: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/170.jpg)
./app/templates/loading.hbs
1 <div class="loading-page"> 2 {{md-loader}} 3 </div>
![Page 171: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/171.jpg)
./app/templates/loading.hbs
2 {{md-loader}}
![Page 172: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/172.jpg)
demo
![Page 173: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/173.jpg)
Our App
![Page 174: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/174.jpg)
Our App
![Page 175: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/175.jpg)
$ ember generate component subscribe-form
![Page 176: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/176.jpg)
Components Are Reusable
![Page 177: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/177.jpg)
Components Are Reusable
![Page 178: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/178.jpg)
Our App
![Page 179: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/179.jpg)
./app/templates/index.hbs
1 <div class="home-feature"> 2 <div class="feature-content row"> 3 <div class="col m6"> 4 <h1>{{t 'index.headline'}}</h1> 5 <h3>{{t 'index.subTitle'}}</h3> 6 <div class="about-link"> 7 {{#link-to 'about'}} 8 <img src="/images/banana_grabber.png"> 9 {{/link-to}} 10 </div> 11 </div> 12 <div class="subscribe-container col m6"> 13 {{subscribe-form model=model}} 14 </div> 15 </div> 16 </div>
![Page 180: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/180.jpg)
./app/templates/index.hbs
13 {{subscribe-form model=model}}
![Page 181: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/181.jpg)
$ ember generatemodel email-subscription
![Page 182: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/182.jpg)
./app/models/email-subscription.js
1 import DS from 'ember-data'; 2 3 export default DS.Model.extend({ 4 email: DS.attr('string'), 5 marketing: DS.attr('boolean', { 6 defaultValue: true 7 }) 8 });
![Page 183: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/183.jpg)
./app/models/email-subscription.js
5 marketing: DS.attr('boolean', { 6 defaultValue: true 7 })
![Page 184: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/184.jpg)
./app/routes/index.js
1 import Ember from 'ember'; 2 3 export default Ember.Route.extend({ 4 model() { 5 return this.get('store').createRecord('email-subscription'); 6 } 7 });
![Page 185: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/185.jpg)
./app/routes/index.js
5 return this.get(‘store') .createRecord('email-subscription');
![Page 186: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/186.jpg)
./app/templates/components/subscribe-form.hbs
1 {{#md-card title=title}} 2 {{#if saved}} 3 {{#md-card-content}} 4 {{t 'subscribe.successMessage' email=model.email}} 5 {{/md-card-content}} 6 {{else}} 7 {{#md-card-content}} 8 {{md-input value=model.email label=(t 'subscribe.email.label') 9 type='email' validate=true}} 10 {{md-check checked=model.marketing 11 name=(t 'subscribe.marketing.label')}} 12 {{#if saving}} 13 {{md-loader}} 14 {{/if}} 15 {{/md-card-content}} 16 {{#md-card-action}} 17 <button {{action 'subscribe'}}> 18 {{t 'subscribe.submit'}} 19 </button> 20 {{/md-card-action}} 21 {{/if}} 22 {{/md-card}}
![Page 187: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/187.jpg)
./app/templates/components/subscribe-form.hbs
8 {{md-input value=model.email label=(t subscribe.email.label') 9 type='email' validate=true}}
![Page 188: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/188.jpg)
./app/templates/components/subscribe-form.hbs
1 {{#md-card title=title}} 2 {{#if saved}} 3 {{#md-card-content}} 4 {{t 'subscribe.successMessage' email=model.email}} 5 {{/md-card-content}} 6 {{else}} 7 {{#md-card-content}} 8 {{md-input value=model.email label=(t 'subscribe.email.label') 9 type='email' validate=true}} 10 {{md-check checked=model.marketing 11 name=(t 'subscribe.marketing.label')}} 12 {{#if saving}} 13 {{md-loader}} 14 {{/if}} 15 {{/md-card-content}} 16 {{#md-card-action}} 17 <button {{action 'subscribe'}}> 18 {{t 'subscribe.submit'}} 19 </button> 20 {{/md-card-action}} 21 {{/if}} 22 {{/md-card}}
![Page 189: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/189.jpg)
./app/templates/components/subscribe-form.hbs
10 {{md-check checked=model.marketing 11 name=(t 'subscribe.marketing.label')}}
![Page 190: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/190.jpg)
./app/templates/components/subscribe-form.hbs
1 {{#md-card title=title}} 2 {{#if saved}} 3 {{#md-card-content}} 4 {{t 'subscribe.successMessage' email=model.email}} 5 {{/md-card-content}} 6 {{else}} 7 {{#md-card-content}} 8 {{md-input value=model.email label=(t 'subscribe.email.label') 9 type='email' validate=true}} 10 {{md-check checked=model.marketing 11 name=(t 'subscribe.marketing.label')}} 12 {{#if saving}} 13 {{md-loader}} 14 {{/if}} 15 {{/md-card-content}} 16 {{#md-card-action}} 17 <button {{action 'subscribe'}}> 18 {{t 'subscribe.submit'}} 19 </button> 20 {{/md-card-action}} 21 {{/if}} 22 {{/md-card}}
![Page 191: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/191.jpg)
./app/templates/components/subscribe-form.hbs
17 <button {{action 'subscribe'}}> 18 {{t 'subscribe.submit'}} 19 </button>
![Page 192: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/192.jpg)
./app/components/subscribe-form.js
1 import Ember from 'ember'; 2 3 export default Ember.Component.extend({ 4 i18n: Ember.inject.service('i18n'), 5 title: Ember.computed('saved', function() { 6 if (this.get('saved')) { 7 return this.get('i18n').t('subscribe.successHeader'); 8 } else { 9 return this.get('i18n').t('subscribe.header'); 10 } 11 }), 12 saved: false, 13 actions: { 14 subscribe() { 15 this.set('saving', true); 16 this.get('model').save().then(() => { 17 this.set('saving', false); 18 this.set('saved', true); 19 }, () => { 20 //error handling here 21 }); 22 } 23 } 24 });
![Page 193: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/193.jpg)
./app/components/subscribe-form.js
5 title: Ember.computed('saved', function() { 6 if (this.get('saved')) { 7 return this.get('i18n').t('subscribe.successHeader'); 8 } else { 9 return this.get('i18n').t('subscribe.header'); 10 } 11 }),
![Page 194: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/194.jpg)
./app/components/subscribe-form.js
1 import Ember from 'ember'; 2 3 export default Ember.Component.extend({ 4 i18n: Ember.inject.service('i18n'), 5 title: Ember.computed('saved', function() { 6 if (this.get('saved')) { 7 return this.get('i18n').t('subscribe.successHeader'); 8 } else { 9 return this.get('i18n').t('subscribe.header'); 10 } 11 }), 12 saved: false, 13 actions: { 14 subscribe() { 15 this.set('saving', true); 16 this.get('model').save().then(() => { 17 this.set('saving', false); 18 this.set('saved', true); 19 }, () => { 20 //error handling here 21 }); 22 } 23 } 24 });
![Page 195: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/195.jpg)
./app/components/subscribe-form.js
13 actions: { 14 subscribe() { 15 this.set('saving', true); 16 this.get('model').save().then(() => { 17 this.set('saving', false); 18 this.set('saved', true); 19 }, () => { 20 //error handling here 21 }); 22 } 23 }
![Page 196: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/196.jpg)
./app/mirage/config.js
1 export default function() { 2 this.timing = 2000; 3 4 this.get('/companyAddresses', 'company-addresses'); 5 6 this.post('/emailSubscriptions', 7 'email-subscriptions'); 8 }
![Page 197: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/197.jpg)
./app/mirage/config.js
6 this.post('/emailSubscriptions', 7 'email-subscriptions');
![Page 198: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/198.jpg)
demo
![Page 199: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/199.jpg)
./tests/integration/components/subscribe-form-test.js
1 test('it renders', function(assert) { 2 assert.expect(3); 3 4 this.render(hbs`{{subscribe-form}}`); 5 6 assert.equal( 7 this.$('.card-title').text().trim(), 8 'Subscribe for updates on the stand.' 9 ); 10 11 assert.equal( 12 this.$('.input-field label').text().trim(), 13 'Please enter your email address.' 14 ); 15 16 assert.equal( 17 this.$('.materialize-checkbox label').text().trim(), 18 'Yes I would like to receive marketing material from Bluth sponsors. 19 ' 20 ); 21 22 });
![Page 200: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/200.jpg)
./tests/acceptance/index-test.hbs 1 test('subscribe for updates', function(assert) { 2 visit('/'); 3 4 fillIn( 5 '.subscribe-container .input-field input', 6 '[email protected]' 7 ); 8 click('.card-action button'); 9 andThen(() => { 10 // stays on index 11 assert.equal(currentURL(), '/'); 12 13 assert.equal( 14 find('.subscribe-container .card-title').text().trim(), 15 'Thanks for signing up.' 16 ); 17 assert.equal( 18 find('.card p').text().trim(), 19 'We\'ll send all of our updates to [email protected].' 20 ); 21 }); 22 23 });
![Page 201: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/201.jpg)
test demo
![Page 202: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/202.jpg)
what we just built
![Page 204: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/204.jpg)
ibotta.com/careers
![Page 205: Building a Single Page Application using Ember.js ... for fun and profit](https://reader034.fdocuments.us/reader034/viewer/2022042707/58e588701a28abbf5d8b63cd/html5/thumbnails/205.jpg)
Thanks!