SlideShare a Scribd company logo
Redux + RxJS + Ember
Justin Park
Managing state stuff is hard
• Specially in Ember
• Controller/Router/Component/ChildCompone
nt
Ember.Object is painful
{{search-pill lastDays=lastDays}}
{{advanced-search lastDays=lastDays…}}
this.set(‘lastDays’, ‘’);
Const MIN_VALUE = 1;
Ember.observer(‘lastDays’, ()=> {
if (this.get(‘lastDays’) < MIN_VALUE) this.set(‘lastDays’, MIN_VALUE);
});
{{search-pill lastDays=lastDays}}
{{advanced-search lastDays=lastDays…}}
Too much!
• addObserver
• cacheFor
• notifyPropertyChange
• removeObserver
• …
• this.setProperties(‘attr1’, { value1: 1, arrKey: [1, 2, {objKey1:
{…}}]});
• {{child-component attr1=attr1}}
• func1(newItem) {
const arr= this.get(‘attr1.arrKey’);
arr.addObject(newItem) // ? or
arr.push(newItem) // ? Or
this.set(‘attr1.arrKey’,Ember.A(arr).addObject(newItem))
…
}
Data Down Action Up
{{my-input
value=(readonly my.prop)
on-change=(action (mut my.prop))}}
• http://emberup.co/bindings-with-htmlbars-helpers/
Redux makes it simple
• Your app is stored in an object tree inside a
single store.
What is redux?
• Provides predicable state management using
actions and reducers
What’s an “action”?
• Describes something has happen, but they don’t
specify how is should be done
• { type: ‘ADD_MSG’, payload: { msg: ‘New Message’}
What’s a “reducer”?
• A pure function that takes the previous state
and an action and returns the new state
What’s a “reducer”?
• Sometimes it returns the previous state
(prevState, action) => state
What’s a “reducer”?
• Sometimes it computes new state
(state, action) => state + action.payload
Each reducer is a separate object
index.js
import alert from './alert';
import search from './search';
import searchParams from './search-params';
import savedSearch from './saved-search';
import router from './router';
Export combineReducers({
alert,
search,
searchParams,
savedSearch,
router,
});
How can I connect?
• Container component
• Presentation component
Container Component
• ember-redux/components/connect
• select(store): read
• actions(dispatch): update
Container ComponentTemplate
• {{yield msgType message isHide}}
(store) => {type: store.alert.type, msg:store.alert.msg, isHide:store.alert.isHide}
{{containers.alert as |type msg isHide|}}
{{alert-message type=type msg=msg isHide=(readonly isHide)}}
{{/containers.alert}}
• {{yield alert=alert}}
(store) => store.alert
{{containers.alert as |alert|}}
{{alert-message type=alert.type msg=alert.msg isHide=(readonly alert.isHide)}}
{{/containers.alert}}
• {{yield (hash msgType=msgType message=message…)}}
(store) => {...store.alert} or return Object.assign({}, store.alert);
{{containers.alert as |alert|}}
{{alert-message type=alert.type msg=alert.msg isHide=(readonly alert.isHide)}}
{{/containers.alert}}
Managing async stuff is harder
RxJS makes it manageable
What are async stuff do we
commonly do?
Async
• User interactions (mouse, keyboard, etc)
• AJAX
• Timer/Animations
• Workers, etc
THIS IS OPTIONAL
MAKE LIFE EASIER
Chains of actions
Scenario of fetching search result
• Loading
• Load the records on success
• Display an error message on fail
• Abort the previous ajax call on new request
• Ignore the duplicate requests
• Subsequence ajax calls, etc…
redux.dispatch({type: LOADING});
this.store.read(‘search’).then(response =>
redux.dispatch({type: LOAD, payload: response});
).fail(error=>
redux.dispatch({type: ERROR, payload:error});
),
redux.dispatch({type: LOADING});
if (this.xhr) { this.xhr.abort(); }
this.xhr = this.store.read(‘search’).then(response =>
redux.dispatch({type: LOAD, payload: response});
).fail(error=>
redux.dispatch({type: ERROR, payload:error});
),
if (shallowEqual(this._preDataParams,dataParams))
return;
redux.dispatch({type: LOADING});
if (this.xhr) { this.xhr.abort(); }
this._prevDataParams = dataParams;
this.xhr = this.store.read(‘search’,
dataParams).then(response =>
redux.dispatch({type: LOAD, payload: response});
).fail(error=>
redux.dispatch({type: ERROR, payload:error});
),
if (shallowEqual(this._preDataParams,dataParams))
return;
redux.dispatch({type: LOADING});
if (this.xhr) { this.xhr.abort(); }
this._prevDataParams = dataParams;
this.xhr = this.store.read(‘search’,
dataParams).then(response =>
redux.dispatch({type: LOAD, payload: response});
).fail(error=>
redux.dispatch({type: ERROR, payload:error});
),
this.xhr.then(response => {
return response.items.map(item =>
this.store.read(‘search-exp’, item.id));
}); …
if (shallowEqual(this._preDataParams,dataParams))
return;
redux.dispatch({type: LOADING});
if (this.xhr) { this.xhr.abort(); }
…
this.xhr.then(response => {
return response.items.map(item =>
this.store.read(‘search-exp’, item.id));
}); …
How can abort these?
(action$) => action$.ofType(LOADING)
.map(action => action.payload)
.mergeMap(payload =>
trexServices.store.read(‘search’)
.map(response => { type: LOAD, payload: data.response })
.catch(() => Observable.of({type: ERROR}))
);
(action$) => action$.ofType(REQUEST_READ)
.map(action => action.payload)
.mergeMap(payload =>
Observable.merge(
Observable.of({type: LOADING}),
trexServices.store.read(‘search’)
.map(ajaxRes => ajaxRes.response)
.map(response => { type: LOAD, payload: response })
.catch(() => Observable.of({type: ERROR}))
)
);
(action$) => action$.ofType(REQUEST_READ)
.map(action => action.payload)
. switchMap(payload =>
Observable.merge(
Observable.of({type: LOADING}),
trexServices.store.read(‘search’)
.map(ajaxRes => ajaxRes.response)
.map(response => { type: LOAD, payload: response })
.catch(() => Observable.of({type: ERROR}))
)
);
const comparator =
(objA, objB) => shallowEqual(objA.dataParams, objB.dataParams);
(action$) => action$.ofType(REQUEST_READ)
.map(action => action.payload)
.distinctUntilChanged(comparator)
.switchMap(payload =>
Observable.merge(
Observable.of({type: LOADING}),
trexServices.store.read(‘search’, payload.dataParams)
.map(ajaxRes => ajaxRes.response)
.map(response => { type: LOAD, payload: response })
.catch(() => Observable.of({type: ERROR}))
)
);
(action$) => action$.ofType(LOAD)
.filter(([items]) => items.id)
.switchMap(([source, items]) =>
Observable
.mergeMap(() => Observable.merge(
...items.map(item=>
trexServices.store.read(‘search-exp’, item.id)
.map({type: LOAD_EXP, payload => response)
)
))
.catch(() => Observable.of(Actions.requestFail()))
);
Demo

More Related Content

PDF
Rethink Async With RXJS
PPTX
Rxjs ngvikings
PPTX
Rxjs swetugg
PDF
Rxjs vienna
PDF
MongoDB World 2019: Life In Stitch-es
PDF
High Performance Core Data
PDF
Core Data with multiple managed object contexts
PDF
Create a Core Data Observer in 10mins
Rethink Async With RXJS
Rxjs ngvikings
Rxjs swetugg
Rxjs vienna
MongoDB World 2019: Life In Stitch-es
High Performance Core Data
Core Data with multiple managed object contexts
Create a Core Data Observer in 10mins

What's hot (20)

PDF
Persisting Data on SQLite using Room
PDF
Browser testing with nightwatch.js - Drupal Europe
PDF
Mongodb debugging-performance-problems
PDF
0 to App faster with NodeJS and Ruby
PDF
C* Summit EU 2013: Cassandra Made Simple with CQL Drivers and DevCenter
PDF
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
PDF
iOS for ERREST - alternative version
KEY
Sexy.js: A Sequential Ajax (Sajax) library for jQuery
PPTX
PostgreSQL's Secret NoSQL Superpowers
PDF
Lazy evaluation drupal camp moscow 2014
PDF
Matteo Collina | Take your HTTP server to Ludicrous Speed | Codmeotion Madrid...
PDF
Building Smart Async Functions For Mobile
PPTX
Using Arbor/ RGraph JS libaries for Data Visualisation
PDF
The Ring programming language version 1.6 book - Part 70 of 189
PDF
MongoDB Performance Debugging
PPTX
The next step, part 2
KEY
iOSDevCamp 2011 Core Data
PPTX
Dbabstraction
PPT
Zend framework 03 - singleton factory data mapper caching logging
PDF
ERGroupware
Persisting Data on SQLite using Room
Browser testing with nightwatch.js - Drupal Europe
Mongodb debugging-performance-problems
0 to App faster with NodeJS and Ruby
C* Summit EU 2013: Cassandra Made Simple with CQL Drivers and DevCenter
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
iOS for ERREST - alternative version
Sexy.js: A Sequential Ajax (Sajax) library for jQuery
PostgreSQL's Secret NoSQL Superpowers
Lazy evaluation drupal camp moscow 2014
Matteo Collina | Take your HTTP server to Ludicrous Speed | Codmeotion Madrid...
Building Smart Async Functions For Mobile
Using Arbor/ RGraph JS libaries for Data Visualisation
The Ring programming language version 1.6 book - Part 70 of 189
MongoDB Performance Debugging
The next step, part 2
iOSDevCamp 2011 Core Data
Dbabstraction
Zend framework 03 - singleton factory data mapper caching logging
ERGroupware
Ad

Similar to Redux + RxJS + Ember makes simple (20)

PDF
Secrets of JavaScript Libraries
PDF
Think Async: Asynchronous Patterns in NodeJS
KEY
Object-Oriented JavaScript
KEY
Object-Oriented Javascript
PDF
Ten useful JavaScript tips & best practices
PDF
What's new in jQuery 1.5
PDF
Introduction to Protractor
PDF
Road to react hooks
PDF
Activator and Reactive at Play NYC meetup
PDF
Service worker: discover the next web game changer
PDF
You will learn RxJS in 2017
KEY
Polyglot parallelism
PPTX
Async Web QA
PPTX
Async Redux Actions With RxJS - React Rally 2016
KEY
NodeJS
PDF
JavaScript Fundamentals with Angular and Lodash
PPTX
Javascript And J Query
PPTX
JavaScript Promises
PDF
Ember background basics
PDF
Matthew Eernisse, NodeJs, .toster {webdev}
Secrets of JavaScript Libraries
Think Async: Asynchronous Patterns in NodeJS
Object-Oriented JavaScript
Object-Oriented Javascript
Ten useful JavaScript tips & best practices
What's new in jQuery 1.5
Introduction to Protractor
Road to react hooks
Activator and Reactive at Play NYC meetup
Service worker: discover the next web game changer
You will learn RxJS in 2017
Polyglot parallelism
Async Web QA
Async Redux Actions With RxJS - React Rally 2016
NodeJS
JavaScript Fundamentals with Angular and Lodash
Javascript And J Query
JavaScript Promises
Ember background basics
Matthew Eernisse, NodeJs, .toster {webdev}
Ad

Recently uploaded (20)

PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PDF
Review of recent advances in non-invasive hemoglobin estimation
PDF
Approach and Philosophy of On baking technology
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PDF
Unlocking AI with Model Context Protocol (MCP)
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PDF
Machine learning based COVID-19 study performance prediction
PDF
Empathic Computing: Creating Shared Understanding
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PDF
Encapsulation_ Review paper, used for researhc scholars
PDF
NewMind AI Weekly Chronicles - August'25 Week I
PPTX
Big Data Technologies - Introduction.pptx
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PDF
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
PDF
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
PDF
Encapsulation theory and applications.pdf
DOCX
The AUB Centre for AI in Media Proposal.docx
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
Chapter 3 Spatial Domain Image Processing.pdf
Review of recent advances in non-invasive hemoglobin estimation
Approach and Philosophy of On baking technology
Reach Out and Touch Someone: Haptics and Empathic Computing
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
Unlocking AI with Model Context Protocol (MCP)
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
Machine learning based COVID-19 study performance prediction
Empathic Computing: Creating Shared Understanding
Digital-Transformation-Roadmap-for-Companies.pptx
Encapsulation_ Review paper, used for researhc scholars
NewMind AI Weekly Chronicles - August'25 Week I
Big Data Technologies - Introduction.pptx
Mobile App Security Testing_ A Comprehensive Guide.pdf
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
Encapsulation theory and applications.pdf
The AUB Centre for AI in Media Proposal.docx

Redux + RxJS + Ember makes simple