SlideShare a Scribd company logo
Mike North
Levanto Financial, Inc.
Ember.js – Modern, Scalable, Ambitious Apps
JS UI LIBRARIES
99 2000 01 02 03 04 05 06 07 08 09 2010 11 12 13 14 15 16 17
2 2
6 7 8 9 10 11 12
ES3 ES5
@MichaelLNorth
NOW IMAGINE…
• All the micro-libraries
• All the build tools
• All the pre-processors and post-processors
• All of the permutations with typescript, babel, etc…
“BEST IN CLASS” OPTIONS FROM EACH
CATEGORY?
WHAT ARE SOME OFTHE MODERN
CHOICES?
2
What our users need us to build
What we’re sometimes tempted to build
What our users need us to build
THE EMBER ECOSYSTEM
ember-cli
Code Generation
Asset Pipeline
Plugins
Extensible CLI
Test Runner
ember.js
SPA routing
Components
Templating
Data Binding
Prioritized Work Queue
ember-data
Request Construction
JSON Serialization
Redux-like Data Flow
Async Relationships
liquid-fire
animations
ember-collection
virtualized list
THE EMBER ECOSYSTEM
• Built on strong conventions & opinions
• Focus on developer productivity
• Aligned with web standards
• Abstractions hold up w/ large scale & complexity
• Constantly improving
TEMPLATING
• Handlebars
• Declarative markup, an extension of
HTML
• Compiled at build time
• Extensible
Hello,
<strong>
{{firstName}} {{lastName}}
</strong>!
define('examples/templates/index', ['exports'], function (exports) {
'use strict';
exports['default'] = Ember.HTMLBars.template((function() {
return {
...
buildFragment: function buildFragment(dom) {
var el0 = dom.createDocumentFragment();
var el1 = dom.createTextNode("Hello, ");
dom.appendChild(el0, el1);
var el1 = dom.createElement("strong");
var el2 = dom.createComment("");
dom.appendChild(el1, el2);
var el2 = dom.createTextNode(" ");
dom.appendChild(el1, el2);
var el2 = dom.createComment("");
dom.appendChild(el1, el2);
dom.appendChild(el0, el1);
var el1 = dom.createTextNode("!");
dom.appendChild(el0, el1);
return el0;
},
buildRenderNodes: function buildRenderNodes(dom, fragment,
contextualElement) {
var element0 = dom.childAt(fragment, [1]);
var morphs = new Array(2);
morphs[0] = dom.createMorphAt(element0,0,0);
morphs[1] = dom.createMorphAt(element0,2,2);
return morphs;
},
statements: [
["content","firstName",["loc",[null,[1,15],[1,28]]]],
["content","lastName",["loc",[null,[1,29],[1,41]]]]
],
...
};
}()));
});
TEMPLATING
• Helpers
• Block vs inline form
• Easy to read and reason about
My pet goes
{{#if isDog}}
arf
{{else}}
meow
{{/if}}
My pet goes {{if isDog "arf"
"meow"}}
My pet goes {{if isDog "arf" "meow"}}
function ifHelper(condition, ifTrue, ifFalse) {
return condition ? ifTrue : ifFalse
}
{{#if isEnabled}}
<b>Switch is enabled</b>
{{/if}}
function ifHelper(condition, callbackIfTrue) {
return condition ? callbackIfTrue() : '';
}
<ul>
{{#each arr as |item|}}
<li>{{item.name}}</li>
{{/each}}
</ul>
function eachHelper(array, cb) {
return array
.map(item => cb(item))
.join('');
}
ROUTING
• Router - Finite State Machine
• Routes - Manage transitions between
states
• URLs drive your app this is a core pillar
of Ember
ROUTING
ember
routing
URL changes
components templates
HTML++
ember-data
store adapter
makes requests
serializer
transforms JSON
Talks to API
application
index
application
posts post
author comments
index
index index
indexindex
/URL:
application
posts
posts/index
application
posts post
author comments
index
index index
indexindex
/posts/URL:
application
post
post/index
application
posts post
author comments
index
index index
indexindex
/post/31URL:
application
post
application
posts post
author comments
index
index index
indexindex
{{outlet}}
/post/31/comments/URL:
application
post
application
posts post
author comments
index
index index
indexindex
post/comments
post/comments/index
/post/31/comments/URL:
COMPONENTS
How many of you have been using some
type of web component for > 5 years?
COMPONENTS
<my-widget title='Enter your Info'>
<my-field name='Username'/>
<my-field name='Password'/>
</my-widget>
W3C WEB COMPONENT SPEC IS
INCOMPLETE!
…ANDTHIS IS A GOODTHING
WEB UI LIBS ARE JUST A GIANT SERIES OF
HACKS
TC39
<my-widget title='Enter your Info'>
<my-field name='Username'/>
<my-field name='Password'/>
</my-widget>
{{#my-widget title='Enter your Info’}}
{{my-field name=‘Username’}}
{{my-field name=‘Password’}}
{{/my-widget}}
init on instantiation
willInsertElement before the component’s element is inserted into the DOM
didInsertElement after the component’s element has been inserted into the DOM
willDestroyElement before the component’s element is removed from the DOM
$(document).ready() for components
Clean up before tear down
EMBER.COMPONENT
EMBER-DATA
• Unidirectional data flow, single atom of state
• Can talk to any API
• Moves data massaging out of your business logic
• Built around fetch (important for SS rendering!)
• Saves tons of time if your API uses consistent conventions
EMBER-DATA: MODEL
• Representation of any (usually
persistent) data
• Defined by attributes, and
relationships to other models
• “model” is the factory that defines
the structure of “records”
// app/models/book.js
import DS from 'ember-data';
const { attr, hasMany } = DS;
export default DS.Model.extend({
title: attr('string'),
publishedAt: attr('date'),
chapters: hasMany('chapter')
});
EMBER-DATA: STORE
• Where you get/create/destroy records
• A single source of truth
• This means that all changes are kept in sync!
• Similar concept in Facebook/flux, angular-data
EMBER-DATA: STORE
// (maybe) API request for all records of type "author"
this.store.findAll('author');
// (maybe) API request for record of type "post" with id 37
this.store.findRecord('post', 37);
// API request for all records of type "author"
this.store.fetchAll('author');
// API request for record of type "post" with id 37
this.store.fetchRecord('post', 37);
// look in cache for all records of type "author"
this.store.peekAll('author');
// look in cache for record of type "post" with id 37
this.store.peekRecord('post', 37);
EMBER-DATA:ADAPTER
export default DS.RESTAdapter.extend({
host: 'https://api.github.com',
urlForQuery (query, modelName) {
switch(modelName) {
case 'repo':
return `${this.get('host')}/orgs/${query.orgId}/repos`;
default:
return this._super(...arguments);
}
}
});
EMBER-DATA: SERIALIZER
export default DS.RESTSerializer.extend({
normalizeResponse(store, modelClass, payload, id, requestType){
const newPayload = { org: payload };
return this._super(store, modelClass, newPayload, id, requestType);
}
});
EMBER-CLI
ADOPTION
RECENT DEVELOPMENTS
FASTBOOT
ENGINES
GLIMMER 2
…AND MORE…
THANKS!
COME TO THE EMBER.JS WORKSHOP!

More Related Content

What's hot

Elasticsearch for SQL Users
Elasticsearch for SQL UsersElasticsearch for SQL Users
Elasticsearch for SQL Users
All Things Open
 
Painless Persistence in a Disconnected World
Painless Persistence in a Disconnected WorldPainless Persistence in a Disconnected World
Painless Persistence in a Disconnected World
Christian Melchior
 
Recipes to build Code Generators for Non-Xtext Models with Xtend
Recipes to build Code Generators for Non-Xtext Models with XtendRecipes to build Code Generators for Non-Xtext Models with Xtend
Recipes to build Code Generators for Non-Xtext Models with Xtend
Karsten Thoms
 
Modernizing WordPress Search with Elasticsearch
Modernizing WordPress Search with ElasticsearchModernizing WordPress Search with Elasticsearch
Modernizing WordPress Search with Elasticsearch
Taylor Lovett
 
Relate
RelateRelate
Activator and Reactive at Play NYC meetup
Activator and Reactive at Play NYC meetupActivator and Reactive at Play NYC meetup
Activator and Reactive at Play NYC meetup
Henrik Engström
 
SenchaCon 2016: How to Auto Generate a Back-end in Minutes - Per Minborg, Emi...
SenchaCon 2016: How to Auto Generate a Back-end in Minutes - Per Minborg, Emi...SenchaCon 2016: How to Auto Generate a Back-end in Minutes - Per Minborg, Emi...
SenchaCon 2016: How to Auto Generate a Back-end in Minutes - Per Minborg, Emi...
Sencha
 
Nodejs functional programming and schema validation lightning talk
Nodejs   functional programming and schema validation lightning talkNodejs   functional programming and schema validation lightning talk
Nodejs functional programming and schema validation lightning talkDeepank Gupta
 
dotNet Miami - June 21, 2012: Richie Rump: Entity Framework: Code First and M...
dotNet Miami - June 21, 2012: Richie Rump: Entity Framework: Code First and M...dotNet Miami - June 21, 2012: Richie Rump: Entity Framework: Code First and M...
dotNet Miami - June 21, 2012: Richie Rump: Entity Framework: Code First and M...
dotNet Miami
 
Dcm#8 elastic search
Dcm#8  elastic searchDcm#8  elastic search
Dcm#8 elastic search
Ivan Wallarm
 
Crafting Evolvable Api Responses
Crafting Evolvable Api ResponsesCrafting Evolvable Api Responses
Crafting Evolvable Api Responses
darrelmiller71
 
Modernizes your objective C - Oliviero
Modernizes your objective C - OlivieroModernizes your objective C - Oliviero
Modernizes your objective C - Oliviero
Codemotion
 
Barcamp Auckland Rails3 presentation
Barcamp Auckland Rails3 presentationBarcamp Auckland Rails3 presentation
Barcamp Auckland Rails3 presentation
Sociable
 
Elixir and Phoenix for Rubyists
Elixir and Phoenix for RubyistsElixir and Phoenix for Rubyists
Elixir and Phoenix for Rubyists
Brooklyn Zelenka
 
Apache poi tutorial
Apache poi tutorialApache poi tutorial
Apache poi tutorial
Ramakrishna kapa
 
The JSON REST API for WordPress
The JSON REST API for WordPressThe JSON REST API for WordPress
The JSON REST API for WordPress
Taylor Lovett
 
Elastic search Walkthrough
Elastic search WalkthroughElastic search Walkthrough
Elastic search Walkthrough
Suhel Meman
 
Introduction to CouchDB
Introduction to CouchDBIntroduction to CouchDB
Introduction to CouchDB
OpusVL
 
Elasticsearch in 15 minutes
Elasticsearch in 15 minutesElasticsearch in 15 minutes
Elasticsearch in 15 minutes
David Pilato
 

What's hot (20)

Elasticsearch for SQL Users
Elasticsearch for SQL UsersElasticsearch for SQL Users
Elasticsearch for SQL Users
 
Painless Persistence in a Disconnected World
Painless Persistence in a Disconnected WorldPainless Persistence in a Disconnected World
Painless Persistence in a Disconnected World
 
Recipes to build Code Generators for Non-Xtext Models with Xtend
Recipes to build Code Generators for Non-Xtext Models with XtendRecipes to build Code Generators for Non-Xtext Models with Xtend
Recipes to build Code Generators for Non-Xtext Models with Xtend
 
Modernizing WordPress Search with Elasticsearch
Modernizing WordPress Search with ElasticsearchModernizing WordPress Search with Elasticsearch
Modernizing WordPress Search with Elasticsearch
 
Relate
RelateRelate
Relate
 
Activator and Reactive at Play NYC meetup
Activator and Reactive at Play NYC meetupActivator and Reactive at Play NYC meetup
Activator and Reactive at Play NYC meetup
 
SenchaCon 2016: How to Auto Generate a Back-end in Minutes - Per Minborg, Emi...
SenchaCon 2016: How to Auto Generate a Back-end in Minutes - Per Minborg, Emi...SenchaCon 2016: How to Auto Generate a Back-end in Minutes - Per Minborg, Emi...
SenchaCon 2016: How to Auto Generate a Back-end in Minutes - Per Minborg, Emi...
 
Nodejs functional programming and schema validation lightning talk
Nodejs   functional programming and schema validation lightning talkNodejs   functional programming and schema validation lightning talk
Nodejs functional programming and schema validation lightning talk
 
dotNet Miami - June 21, 2012: Richie Rump: Entity Framework: Code First and M...
dotNet Miami - June 21, 2012: Richie Rump: Entity Framework: Code First and M...dotNet Miami - June 21, 2012: Richie Rump: Entity Framework: Code First and M...
dotNet Miami - June 21, 2012: Richie Rump: Entity Framework: Code First and M...
 
Underscore
UnderscoreUnderscore
Underscore
 
Dcm#8 elastic search
Dcm#8  elastic searchDcm#8  elastic search
Dcm#8 elastic search
 
Crafting Evolvable Api Responses
Crafting Evolvable Api ResponsesCrafting Evolvable Api Responses
Crafting Evolvable Api Responses
 
Modernizes your objective C - Oliviero
Modernizes your objective C - OlivieroModernizes your objective C - Oliviero
Modernizes your objective C - Oliviero
 
Barcamp Auckland Rails3 presentation
Barcamp Auckland Rails3 presentationBarcamp Auckland Rails3 presentation
Barcamp Auckland Rails3 presentation
 
Elixir and Phoenix for Rubyists
Elixir and Phoenix for RubyistsElixir and Phoenix for Rubyists
Elixir and Phoenix for Rubyists
 
Apache poi tutorial
Apache poi tutorialApache poi tutorial
Apache poi tutorial
 
The JSON REST API for WordPress
The JSON REST API for WordPressThe JSON REST API for WordPress
The JSON REST API for WordPress
 
Elastic search Walkthrough
Elastic search WalkthroughElastic search Walkthrough
Elastic search Walkthrough
 
Introduction to CouchDB
Introduction to CouchDBIntroduction to CouchDB
Introduction to CouchDB
 
Elasticsearch in 15 minutes
Elasticsearch in 15 minutesElasticsearch in 15 minutes
Elasticsearch in 15 minutes
 

Similar to Modern, Scalable, Ambitious apps with Ember.js

Entity Framework: Code First and Magic Unicorns
Entity Framework: Code First and Magic UnicornsEntity Framework: Code First and Magic Unicorns
Entity Framework: Code First and Magic UnicornsRichie Rump
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...Fabio Franzini
 
Michael North "Ember.js 2 - Future-friendly ambitious apps, that scale!"
Michael North "Ember.js 2 - Future-friendly ambitious apps, that scale!"Michael North "Ember.js 2 - Future-friendly ambitious apps, that scale!"
Michael North "Ember.js 2 - Future-friendly ambitious apps, that scale!"
Fwdays
 
Simon Elliston Ball – When to NoSQL and When to Know SQL - NoSQL matters Barc...
Simon Elliston Ball – When to NoSQL and When to Know SQL - NoSQL matters Barc...Simon Elliston Ball – When to NoSQL and When to Know SQL - NoSQL matters Barc...
Simon Elliston Ball – When to NoSQL and When to Know SQL - NoSQL matters Barc...
NoSQLmatters
 
05 integrate redis
05 integrate redis05 integrate redis
05 integrate redis
Erhwen Kuo
 
Entity framework introduction sesion-1
Entity framework introduction   sesion-1Entity framework introduction   sesion-1
Entity framework introduction sesion-1
Usama Nada
 
Intro To Spring Python
Intro To Spring PythonIntro To Spring Python
Intro To Spring Python
gturnquist
 
The Road To Damascus - A Conversion Experience: LotusScript and @Formula to SSJS
The Road To Damascus - A Conversion Experience: LotusScript and @Formula to SSJSThe Road To Damascus - A Conversion Experience: LotusScript and @Formula to SSJS
The Road To Damascus - A Conversion Experience: LotusScript and @Formula to SSJS
mfyleman
 
MongoDB at ZPUGDC
MongoDB at ZPUGDCMongoDB at ZPUGDC
MongoDB at ZPUGDC
Mike Dirolf
 
Building nTier Applications with Entity Framework Services (Part 1)
Building nTier Applications with Entity Framework Services (Part 1)Building nTier Applications with Entity Framework Services (Part 1)
Building nTier Applications with Entity Framework Services (Part 1)
David McCarter
 
System insight without Interference
System insight without InterferenceSystem insight without Interference
System insight without Interference
Tony Tam
 
Speedment - Reactive programming for Java8
Speedment - Reactive programming for Java8Speedment - Reactive programming for Java8
Speedment - Reactive programming for Java8
Speedment, Inc.
 
Allura - an Open Source MongoDB Based Document Oriented SourceForge
Allura - an Open Source MongoDB Based Document Oriented SourceForgeAllura - an Open Source MongoDB Based Document Oriented SourceForge
Allura - an Open Source MongoDB Based Document Oriented SourceForge
Rick Copeland
 
Building nTier Applications with Entity Framework Services (Part 1)
Building nTier Applications with Entity Framework Services (Part 1)Building nTier Applications with Entity Framework Services (Part 1)
Building nTier Applications with Entity Framework Services (Part 1)
David McCarter
 
Intro to node and mongodb 1
Intro to node and mongodb   1Intro to node and mongodb   1
Intro to node and mongodb 1Mohammad Qureshi
 
CoreML for NLP (Melb Cocoaheads 08/02/2018)
CoreML for NLP (Melb Cocoaheads 08/02/2018)CoreML for NLP (Melb Cocoaheads 08/02/2018)
CoreML for NLP (Melb Cocoaheads 08/02/2018)
Hon Weng Chong
 
Ruby On Rails
Ruby On RailsRuby On Rails
Ruby On Rails
Balint Erdi
 
Domain oriented development
Domain oriented developmentDomain oriented development
Domain oriented development
rajmundr
 
The Why and How of Scala at Twitter
The Why and How of Scala at TwitterThe Why and How of Scala at Twitter
The Why and How of Scala at Twitter
Alex Payne
 

Similar to Modern, Scalable, Ambitious apps with Ember.js (20)

Entity Framework: Code First and Magic Unicorns
Entity Framework: Code First and Magic UnicornsEntity Framework: Code First and Magic Unicorns
Entity Framework: Code First and Magic Unicorns
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...
 
Michael North "Ember.js 2 - Future-friendly ambitious apps, that scale!"
Michael North "Ember.js 2 - Future-friendly ambitious apps, that scale!"Michael North "Ember.js 2 - Future-friendly ambitious apps, that scale!"
Michael North "Ember.js 2 - Future-friendly ambitious apps, that scale!"
 
Simon Elliston Ball – When to NoSQL and When to Know SQL - NoSQL matters Barc...
Simon Elliston Ball – When to NoSQL and When to Know SQL - NoSQL matters Barc...Simon Elliston Ball – When to NoSQL and When to Know SQL - NoSQL matters Barc...
Simon Elliston Ball – When to NoSQL and When to Know SQL - NoSQL matters Barc...
 
05 integrate redis
05 integrate redis05 integrate redis
05 integrate redis
 
Entity framework introduction sesion-1
Entity framework introduction   sesion-1Entity framework introduction   sesion-1
Entity framework introduction sesion-1
 
Intro To Spring Python
Intro To Spring PythonIntro To Spring Python
Intro To Spring Python
 
Java days gbg online
Java days gbg onlineJava days gbg online
Java days gbg online
 
The Road To Damascus - A Conversion Experience: LotusScript and @Formula to SSJS
The Road To Damascus - A Conversion Experience: LotusScript and @Formula to SSJSThe Road To Damascus - A Conversion Experience: LotusScript and @Formula to SSJS
The Road To Damascus - A Conversion Experience: LotusScript and @Formula to SSJS
 
MongoDB at ZPUGDC
MongoDB at ZPUGDCMongoDB at ZPUGDC
MongoDB at ZPUGDC
 
Building nTier Applications with Entity Framework Services (Part 1)
Building nTier Applications with Entity Framework Services (Part 1)Building nTier Applications with Entity Framework Services (Part 1)
Building nTier Applications with Entity Framework Services (Part 1)
 
System insight without Interference
System insight without InterferenceSystem insight without Interference
System insight without Interference
 
Speedment - Reactive programming for Java8
Speedment - Reactive programming for Java8Speedment - Reactive programming for Java8
Speedment - Reactive programming for Java8
 
Allura - an Open Source MongoDB Based Document Oriented SourceForge
Allura - an Open Source MongoDB Based Document Oriented SourceForgeAllura - an Open Source MongoDB Based Document Oriented SourceForge
Allura - an Open Source MongoDB Based Document Oriented SourceForge
 
Building nTier Applications with Entity Framework Services (Part 1)
Building nTier Applications with Entity Framework Services (Part 1)Building nTier Applications with Entity Framework Services (Part 1)
Building nTier Applications with Entity Framework Services (Part 1)
 
Intro to node and mongodb 1
Intro to node and mongodb   1Intro to node and mongodb   1
Intro to node and mongodb 1
 
CoreML for NLP (Melb Cocoaheads 08/02/2018)
CoreML for NLP (Melb Cocoaheads 08/02/2018)CoreML for NLP (Melb Cocoaheads 08/02/2018)
CoreML for NLP (Melb Cocoaheads 08/02/2018)
 
Ruby On Rails
Ruby On RailsRuby On Rails
Ruby On Rails
 
Domain oriented development
Domain oriented developmentDomain oriented development
Domain oriented development
 
The Why and How of Scala at Twitter
The Why and How of Scala at TwitterThe Why and How of Scala at Twitter
The Why and How of Scala at Twitter
 

More from Mike North

Web Security: A Primer for Developers
Web Security: A Primer for DevelopersWeb Security: A Primer for Developers
Web Security: A Primer for Developers
Mike North
 
A Debugging Adventure: Journey through Ember.js Glue
A Debugging Adventure: Journey through Ember.js GlueA Debugging Adventure: Journey through Ember.js Glue
A Debugging Adventure: Journey through Ember.js Glue
Mike North
 
Anatomy of a Progressive Web App
Anatomy of a Progressive Web AppAnatomy of a Progressive Web App
Anatomy of a Progressive Web App
Mike North
 
Web and Native: Bridging the Gap
Web and Native: Bridging the GapWeb and Native: Bridging the Gap
Web and Native: Bridging the Gap
Mike North
 
The Road to Native Web Components
The Road to Native Web ComponentsThe Road to Native Web Components
The Road to Native Web Components
Mike North
 
Enemy of the state
Enemy of the stateEnemy of the state
Enemy of the state
Mike North
 
Phoenix for Rubyists - Rubyconf Brazil 2016
Phoenix for Rubyists - Rubyconf Brazil 2016Phoenix for Rubyists - Rubyconf Brazil 2016
Phoenix for Rubyists - Rubyconf Brazil 2016
Mike North
 
Phoenix for Rubyists
Phoenix for RubyistsPhoenix for Rubyists
Phoenix for Rubyists
Mike North
 
Write Once, Run Everywhere - Ember.js Munich
Write Once, Run Everywhere - Ember.js MunichWrite Once, Run Everywhere - Ember.js Munich
Write Once, Run Everywhere - Ember.js Munich
Mike North
 
Delightful UX for Distributed Systems
Delightful UX for Distributed SystemsDelightful UX for Distributed Systems
Delightful UX for Distributed Systems
Mike North
 
Ember addons, served three ways
Ember addons, served three waysEmber addons, served three ways
Ember addons, served three ways
Mike North
 
CI/CD and Asset Serving for Single Page Apps
CI/CD and Asset Serving for Single Page AppsCI/CD and Asset Serving for Single Page Apps
CI/CD and Asset Serving for Single Page Apps
Mike North
 
User percieved performance
User percieved performanceUser percieved performance
User percieved performance
Mike North
 
User-percieved performance
User-percieved performanceUser-percieved performance
User-percieved performance
Mike North
 
Write Once, Run Everywhere
Write Once, Run EverywhereWrite Once, Run Everywhere
Write Once, Run Everywhere
Mike North
 
Compose all the things (Wicked Good Ember 2015)
Compose all the things (Wicked Good Ember 2015)Compose all the things (Wicked Good Ember 2015)
Compose all the things (Wicked Good Ember 2015)
Mike North
 
Async JavaScript in ES7
Async JavaScript in ES7Async JavaScript in ES7
Async JavaScript in ES7
Mike North
 
Test like a pro with Ember.js
Test like a pro with Ember.jsTest like a pro with Ember.js
Test like a pro with Ember.js
Mike North
 
Modern Web UI - Web components
Modern Web UI - Web componentsModern Web UI - Web components
Modern Web UI - Web components
Mike North
 

More from Mike North (19)

Web Security: A Primer for Developers
Web Security: A Primer for DevelopersWeb Security: A Primer for Developers
Web Security: A Primer for Developers
 
A Debugging Adventure: Journey through Ember.js Glue
A Debugging Adventure: Journey through Ember.js GlueA Debugging Adventure: Journey through Ember.js Glue
A Debugging Adventure: Journey through Ember.js Glue
 
Anatomy of a Progressive Web App
Anatomy of a Progressive Web AppAnatomy of a Progressive Web App
Anatomy of a Progressive Web App
 
Web and Native: Bridging the Gap
Web and Native: Bridging the GapWeb and Native: Bridging the Gap
Web and Native: Bridging the Gap
 
The Road to Native Web Components
The Road to Native Web ComponentsThe Road to Native Web Components
The Road to Native Web Components
 
Enemy of the state
Enemy of the stateEnemy of the state
Enemy of the state
 
Phoenix for Rubyists - Rubyconf Brazil 2016
Phoenix for Rubyists - Rubyconf Brazil 2016Phoenix for Rubyists - Rubyconf Brazil 2016
Phoenix for Rubyists - Rubyconf Brazil 2016
 
Phoenix for Rubyists
Phoenix for RubyistsPhoenix for Rubyists
Phoenix for Rubyists
 
Write Once, Run Everywhere - Ember.js Munich
Write Once, Run Everywhere - Ember.js MunichWrite Once, Run Everywhere - Ember.js Munich
Write Once, Run Everywhere - Ember.js Munich
 
Delightful UX for Distributed Systems
Delightful UX for Distributed SystemsDelightful UX for Distributed Systems
Delightful UX for Distributed Systems
 
Ember addons, served three ways
Ember addons, served three waysEmber addons, served three ways
Ember addons, served three ways
 
CI/CD and Asset Serving for Single Page Apps
CI/CD and Asset Serving for Single Page AppsCI/CD and Asset Serving for Single Page Apps
CI/CD and Asset Serving for Single Page Apps
 
User percieved performance
User percieved performanceUser percieved performance
User percieved performance
 
User-percieved performance
User-percieved performanceUser-percieved performance
User-percieved performance
 
Write Once, Run Everywhere
Write Once, Run EverywhereWrite Once, Run Everywhere
Write Once, Run Everywhere
 
Compose all the things (Wicked Good Ember 2015)
Compose all the things (Wicked Good Ember 2015)Compose all the things (Wicked Good Ember 2015)
Compose all the things (Wicked Good Ember 2015)
 
Async JavaScript in ES7
Async JavaScript in ES7Async JavaScript in ES7
Async JavaScript in ES7
 
Test like a pro with Ember.js
Test like a pro with Ember.jsTest like a pro with Ember.js
Test like a pro with Ember.js
 
Modern Web UI - Web components
Modern Web UI - Web componentsModern Web UI - Web components
Modern Web UI - Web components
 

Recently uploaded

Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
UiPathCommunity
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
Laura Byrne
 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
Frank van Harmelen
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
Ana-Maria Mihalceanu
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Thierry Lestable
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
Product School
 
Generating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using SmithyGenerating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using Smithy
g2nightmarescribd
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
Guy Korland
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Ramesh Iyer
 
Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
Dorra BARTAGUIZ
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Jeffrey Haguewood
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
Jemma Hussein Allen
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and back
Elena Simperl
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
Product School
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
Alan Dix
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
OnBoard
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
Safe Software
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance
 
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
Sri Ambati
 

Recently uploaded (20)

Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
 
Generating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using SmithyGenerating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using Smithy
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
 
Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and back
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
 
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
 

Modern, Scalable, Ambitious apps with Ember.js

  • 1. Mike North Levanto Financial, Inc. Ember.js – Modern, Scalable, Ambitious Apps
  • 2.
  • 3.
  • 4.
  • 5.
  • 6. JS UI LIBRARIES 99 2000 01 02 03 04 05 06 07 08 09 2010 11 12 13 14 15 16 17 2 2 6 7 8 9 10 11 12 ES3 ES5 @MichaelLNorth
  • 7. NOW IMAGINE… • All the micro-libraries • All the build tools • All the pre-processors and post-processors • All of the permutations with typescript, babel, etc…
  • 8. “BEST IN CLASS” OPTIONS FROM EACH CATEGORY?
  • 9.
  • 10. WHAT ARE SOME OFTHE MODERN CHOICES?
  • 11. 2
  • 12.
  • 13. What our users need us to build
  • 14. What we’re sometimes tempted to build
  • 15. What our users need us to build
  • 16. THE EMBER ECOSYSTEM ember-cli Code Generation Asset Pipeline Plugins Extensible CLI Test Runner ember.js SPA routing Components Templating Data Binding Prioritized Work Queue ember-data Request Construction JSON Serialization Redux-like Data Flow Async Relationships liquid-fire animations ember-collection virtualized list
  • 17. THE EMBER ECOSYSTEM • Built on strong conventions & opinions • Focus on developer productivity • Aligned with web standards • Abstractions hold up w/ large scale & complexity • Constantly improving
  • 18. TEMPLATING • Handlebars • Declarative markup, an extension of HTML • Compiled at build time • Extensible Hello, <strong> {{firstName}} {{lastName}} </strong>!
  • 19. define('examples/templates/index', ['exports'], function (exports) { 'use strict'; exports['default'] = Ember.HTMLBars.template((function() { return { ... buildFragment: function buildFragment(dom) { var el0 = dom.createDocumentFragment(); var el1 = dom.createTextNode("Hello, "); dom.appendChild(el0, el1); var el1 = dom.createElement("strong"); var el2 = dom.createComment(""); dom.appendChild(el1, el2); var el2 = dom.createTextNode(" "); dom.appendChild(el1, el2); var el2 = dom.createComment(""); dom.appendChild(el1, el2); dom.appendChild(el0, el1); var el1 = dom.createTextNode("!"); dom.appendChild(el0, el1); return el0; }, buildRenderNodes: function buildRenderNodes(dom, fragment, contextualElement) { var element0 = dom.childAt(fragment, [1]); var morphs = new Array(2); morphs[0] = dom.createMorphAt(element0,0,0); morphs[1] = dom.createMorphAt(element0,2,2); return morphs; }, statements: [ ["content","firstName",["loc",[null,[1,15],[1,28]]]], ["content","lastName",["loc",[null,[1,29],[1,41]]]] ], ... }; }())); });
  • 20. TEMPLATING • Helpers • Block vs inline form • Easy to read and reason about My pet goes {{#if isDog}} arf {{else}} meow {{/if}} My pet goes {{if isDog "arf" "meow"}}
  • 21. My pet goes {{if isDog "arf" "meow"}} function ifHelper(condition, ifTrue, ifFalse) { return condition ? ifTrue : ifFalse } {{#if isEnabled}} <b>Switch is enabled</b> {{/if}} function ifHelper(condition, callbackIfTrue) { return condition ? callbackIfTrue() : ''; }
  • 22. <ul> {{#each arr as |item|}} <li>{{item.name}}</li> {{/each}} </ul> function eachHelper(array, cb) { return array .map(item => cb(item)) .join(''); }
  • 23. ROUTING • Router - Finite State Machine • Routes - Manage transitions between states • URLs drive your app this is a core pillar of Ember
  • 24. ROUTING ember routing URL changes components templates HTML++ ember-data store adapter makes requests serializer transforms JSON Talks to API
  • 28. application post application posts post author comments index index index indexindex {{outlet}} /post/31/comments/URL:
  • 29. application post application posts post author comments index index index indexindex post/comments post/comments/index /post/31/comments/URL:
  • 30. COMPONENTS How many of you have been using some type of web component for > 5 years?
  • 32. <my-widget title='Enter your Info'> <my-field name='Username'/> <my-field name='Password'/> </my-widget>
  • 33. W3C WEB COMPONENT SPEC IS INCOMPLETE!
  • 34. …ANDTHIS IS A GOODTHING WEB UI LIBS ARE JUST A GIANT SERIES OF HACKS
  • 35. TC39
  • 36. <my-widget title='Enter your Info'> <my-field name='Username'/> <my-field name='Password'/> </my-widget> {{#my-widget title='Enter your Info’}} {{my-field name=‘Username’}} {{my-field name=‘Password’}} {{/my-widget}}
  • 37. init on instantiation willInsertElement before the component’s element is inserted into the DOM didInsertElement after the component’s element has been inserted into the DOM willDestroyElement before the component’s element is removed from the DOM $(document).ready() for components Clean up before tear down EMBER.COMPONENT
  • 38. EMBER-DATA • Unidirectional data flow, single atom of state • Can talk to any API • Moves data massaging out of your business logic • Built around fetch (important for SS rendering!) • Saves tons of time if your API uses consistent conventions
  • 39. EMBER-DATA: MODEL • Representation of any (usually persistent) data • Defined by attributes, and relationships to other models • “model” is the factory that defines the structure of “records” // app/models/book.js import DS from 'ember-data'; const { attr, hasMany } = DS; export default DS.Model.extend({ title: attr('string'), publishedAt: attr('date'), chapters: hasMany('chapter') });
  • 40. EMBER-DATA: STORE • Where you get/create/destroy records • A single source of truth • This means that all changes are kept in sync! • Similar concept in Facebook/flux, angular-data
  • 41. EMBER-DATA: STORE // (maybe) API request for all records of type "author" this.store.findAll('author'); // (maybe) API request for record of type "post" with id 37 this.store.findRecord('post', 37); // API request for all records of type "author" this.store.fetchAll('author'); // API request for record of type "post" with id 37 this.store.fetchRecord('post', 37); // look in cache for all records of type "author" this.store.peekAll('author'); // look in cache for record of type "post" with id 37 this.store.peekRecord('post', 37);
  • 42. EMBER-DATA:ADAPTER export default DS.RESTAdapter.extend({ host: 'https://api.github.com', urlForQuery (query, modelName) { switch(modelName) { case 'repo': return `${this.get('host')}/orgs/${query.orgId}/repos`; default: return this._super(...arguments); } } });
  • 43. EMBER-DATA: SERIALIZER export default DS.RESTSerializer.extend({ normalizeResponse(store, modelClass, payload, id, requestType){ const newPayload = { org: payload }; return this._super(store, modelClass, newPayload, id, requestType); } });
  • 46.
  • 52. THANKS! COME TO THE EMBER.JS WORKSHOP!