SlideShare a Scribd company logo
UI Navigation
Mike Nakhimovich
Dispatching State
Mike Nakhimovich
Apps have a UI
Apps have a UI
Search View
Apps have a UI
Search View
ResultsView
Apps have a UI
Search View
ResultsView
ErrorView
Apps have a UI
Search View
ResultsView
ErrorView
LoadingView
Users interact with the UI
Pizza
Interactions lead to State change
Pizza
Pizza
Interactions lead to State change
PizzaPizza
State change need to be rendered
What is state?
A representation of UI
at a certain point in time
What is state?
State determines how the
UI renders & behaves
Android lacks patterns for
working with state & views
How to create state
How to pass state
How to hold state
How do we think about state?
data class ScreenState(
val searchResults:List<Results>,
val searchTerm:String,
val isLoading:Boolean)
Example: state modeled as a single data class
data class ScreenState(
val searchResults:List<Results>,
val searchTerm:String,
val isLoading:Boolean,
val CartItems:List<Items>,
val userId:Long
Example: state modeled as a single growing data class
data class ScreenState(
val searchResults:List<Results>,
val searchTerm:String,
val isLoading:Boolean,
val CartItems:List<Items>,
val userId:Long
State modeled as a God class
Android devs love being reactive,
why not represent state as a stream?
Lately, I’ve been using a
centralized dispatcher to model
state as a reactive stream
What’s a dispatcher?
A dispatcher is an object that receives
and sends messages about state
that the UI reacts to
A dispatcher is an object that receives
and sends messages about state
Why a state dispatcher?
Decouple producers of state
change from its consumers
Why a state dispatcher?
Journey to dispatcher
User types a search term
Pizza
User clicks search
Pizza
Loading should become visible
Pizza
Followed by results
Pizza
Pizza
Proposal 1: Encapsulate Screen
in a ScreenPresenter
How do we tell views what to display?
PizzaScreen Presenter
SearchView ResultsView
Pizza
Proposal 1: Encapsulate Screen
in a ScreenPresenter
How do we tell ResultsViews what to display?
Pizza
But then… Product adds another view
PizzaScreen Presenter
SearchView ResultsViewLoadingView
And then… Product adds 3 more views
Pizza
PizzaScreen Presenter
SearchView ResultsViewLoading
ProfileTab DrawerViewCartView
Proposal 1: Create a ScreenPresenter
which contains both Presenters
How do we tell ResultsView what to display?
Pizza
Not very scalable
How do we tell ResultsView what to display?
Pizza
Proposal 2: Create a Listener
Proposal 2: Create a Listener
Pizza
SearchViewResultsView
Listens To
Proposal 2: Create a Listener
SearchViewResultsView
Listens To
LoadingView
ListensTo
Listens
To
Proposal 2: Create a Listener
Listeners lead to circular dependencies
Last Proposal
Use a centralized dispatcher
for ALL state change
A Dispatcher is responsible for receiving
state changes and emitting them
Use a centralized dispatcher
for ALL state change
Why a state dispatcher?
Views become coupled to the dispatcher not each other
SearchViewResultsView LoadingView
Dispatcher
Reactive state
UI creates new state
Reactive state
UI reacts to new state
Reactive state
With no hard references between UI
elements
Reactive state
Push rather than pull
Implementing reactive state
Reactive state
Sealed class State{
data class ShowingLoading():State
data class ShowingResults(val results:List<String>):State
data class ShowingError(val error:Error):State
}
Represent your state as immutable value objects
Reactive state
Push new state through a reactive stream
Interface Dispatcher
fun dispatch(state: State)
}
interface RxState {
fun <T> ofType(clazz: Class<T>): Observable<T>
}
Sealed class State{
data class ShowingLoading():State
data class ShowingResults(val results:List<String>):State
data class ShowingError(val error:Error):State
}
Reactive state
Anytime UI needs to change, dispatch a new state
dispatcher.dispatch(State.ShowingResults(resultData)
dispatcher.dispatch(State.ShowingLoading()
dispatcher.dispatch(State.ShowingError(errors)
Reactive state
Anytime state changes, react to new state
rxState.ofType(State.Results)
.map{it.data}
.subscribe{ mvpView.updateUI(data) }
Rather than tightly coupling Search & Results
we decouple them with a dispatcher
Reactive state visualized
Dispatcher
Reactive state
ResultsPresenter Subscribes to ShowResults states change
Dispatcher
ResultsPresenter
Reactive state
LoadingPresenter Subscribes to ShowLoading states change
Dispatcher
ResultsPresenter
LoadingPresenter
Reactive state
Dispatcher
SearchPresenterSearchView
SearchTerm
Reactive state
Dispatcher
SearchPresenterSearchView
SearchTerm
ShowingLoading
Reactive state
Dispatcher
SearchPresenterSearchView
SearchTerm
ShowingLoading
Reactive state
Dispatcher
SearchPresenterSearchView
SearchTerm
ShowingLoading
Reactive state
Dispatcher
SearchPresenterSearchView
SearchTerm
ShowingLoading
LoadingPresenter
Reactive state
Dispatcher
SearchPresenterSearchView
SearchTerm
ShowingLoading
LoadingPresenter
Reactive state
Dispatcher
SearchPresenterSearchView
SearchTerm
Reactive state
Search Presenter calls dispatcher.dispatch(State.ShowingResults(resultData)
Dispatcher
SearchPresenterSearchView
SearchTerm
ShowingResults
Reactive state
Dispatcher needs to emit a new State to subscribers
Dispatcher
SearchPresenter
ResultsPresenter
SearchView
SearchTerm
ShowingResults
Reactive state
Dispatcher Emits new ShowingResults State to ResultsPresenter
Dispatcher
SearchPresenter
ResultsPresenter
SearchView
SearchTerm
ShowingResults
Reactive state
Dispatcher Emits new ShowingResults State to subscribers
Dispatcher
SearchPresenterSearchView
SearchTerm
ShowingResults
ResultsPresenter
Reactive state
Dispatcher Emits new ShowingResults State to subscribers
Dispatcher
SearchPresenter
ResultsPresenter
SearchView
SearchTerm
ResultsView
ShowingResults
Reactive state
Multiple Views can listen to same state change Dispatcher
SearchPresenterSearchView
SearchTerm
ResultsPresenterResultsView
LoadingPresenterLoadingView
Reactive state
Dispatcher
SearchPresenterSearchView
ShowingResults
LoadingPresenterLoadingView
ResultsPresenterResultsView
Reactive state
Dispatcher
SearchPresenterSearchView
ShowingResultsShowingResults
LoadingPresenterLoadingView
ResultsPresenterResultsView
Reactive state
Dispatcher
SearchPresenterSearchView
ShowingResults
ShowingResults
LoadingPresenterLoadingView
ResultsPresenterResultsView
Reactive state
Dispatcher
SearchPresenterSearchView
ShowingResults
ShowingResults
LoadingPresenterLoadingView
ResultsPresenterResultsView
Reactive state
Dispatcher
SearchPresenterSearchView
ShowResults
Hide View
LoadingPresenterLoadingView
ResultsPresenterResultsView
Interacting with a dispatcher
Pizza
override fun attachView(view: NearYouMVPView) {
rxState.ofType(State.Results)
.map{it.data}
.subscribe{ mvpView.updateUI(data) }
}
Presenter subscribes on attach
Another presenter dispatches state change
Pizza
fun searchFor(searchTerm:String){
store.getResults(searchTerm)
.subscribe{dispatcher.dispatch(State.Results(data=it.results)}
Dispatcher emits state change
Pizza
fun searchFor(searchTerm:String){
store.getResults(searchTerm)
.subscribe{dispatcher.dispatch(State.Results(data=it.results)}
override fun attachView(view: NearYouMVPView) {
rxState.ofType(State.Results)
.map{it.data}
.subscribe{ mvpView.updateUI(data) }
}
Consumers & Producers of state stay decoupled
Pizza
fun searchFor(searchTerm:String){
store.getResults(searchTerm)
.subscribe{dispatcher.dispatch(State.Results(data=it.results)}
override fun attachView(view: NearYouMVPView) {
rxState.ofType(State.Results)
.map{it.data}
.subscribe{ mvpView.updateUI(data) }
}
How does data flow?
Reactive state
Dispatcher
SearchPresenterSearchView
ResultsPresenterResultsView
Reactive state
Dispatcher
SearchPresenterSearchView
ResultsPresenterResultsView
ShowingResults1
Reactive state
Dispatcher
SearchPresenterSearchView
ResultsPresenterResultsView
ShowingResults1
Reactive state
Dispatcher
SearchPresenterSearchView
ResultsPresenterResultsView
ShowingResults1
Reactive state
Dispatcher
SearchPresenterSearchView
ResultsPresenterResultsView ShowingResults1
Reactive state
Dispatcher
SearchPresenterSearchView
ResultsPresenterResultsView
ShowingResults2
Reactive state
Dispatcher
SearchPresenterSearchView
ResultsPresenterResultsView
ShowingResults2
Reactive state
Dispatcher
SearchPresenterSearchView
ResultsPresenterResultsView
ShowingResults2
Reactive state
Dispatcher
SearchPresenterSearchView
ResultsPresenterResultsView ShowingResults2
Reactive state
Dispatcher
SearchPresenterSearchView
ResultsPresenterResultsView
CartPresenter
More state
Dispatcher
SearchPresenterSearchView
ResultsPresenterResultsView
CartPresenter
Add To Cart
Dispatcher
SearchPresenterSearchView
ResultsPresenterResultsView
CartPresenter
Add To Cart
More state
Dispatcher
SearchPresenterSearchView
ResultsPresenterResultsView
CartPresenter
Add To Cart
More state
Dispatcher
SearchPresenterSearchView
ResultsPresenterResultsView
CartPresenter
Add To Cart
More state
Dispatcher
SearchPresenterSearchView
ResultsPresenterResultsView
CartPresenterCartView
Add To Cart
More state
Dispatcher
SearchPresenterSearchView
ResultsPresenterResultsView
CartPresenterCartView
Add To Cart
More state
Emitting data is nice…
How about showing/hiding views?
When user clicks on cart, we
should show the cart view
HomeScreen
SearchView ResultsViewCartView
How?
We can combine state changes
through composition
Showing states
sealed class State {
object Cart : State()
data class Showing(val state: State) : State()
}
Showing states
dispatcher.dispatch(State.Showing(Cart))
sealed class State {
object Cart : State()
data class Showing(val state: State) : State()
}
Showing states
rxState.showing(Cart::class.java))
.subscribe({
mvpView.showCart()
}))
interface RxState {
fun showingNot(clazz: Class<out Screen>): Observable<Showing>
fun showing(clazz: Class<out Screen>): Observable<Showing>
}
We can show/hide views based on showing states
rxState.showingNot(Cart::class.java))
.subscribe({
mvpView.hide()
}))
rxState.showing(Cart::class.java))
.subscribe({
mvpView.showCart()
}))
Dispatching showing cart
rxState.showingNot(Cart::class.java))
.subscribe({
mvpView.hide()
}))
dispatcher.dispatch(State.Showing(Cart)) rxState.showing(Cart::class.java))
.subscribe({
mvpView.showCart()
}))
Dispatching Showing Checkout
Checkout
rxState.showingNot(Cart::class.java))
.subscribe({
mvpView.hide()
}))
dispatcher.dispatch(State.Showing(Checkout)) rxState.showing(Cart::class.java))
.subscribe({
mvpView.showCart()
}))
Showing/hiding works well
when all views attached
Not very scalable in real apps
Showing/hiding works well
when all views attached
How do we deal with deep flows?
How do we deal with deep flows?
Treat screen creation/routing as a state change
Dispatching screens workflow
Checkout
CartPresenterCartView
Checkout
CartPresenterCartView
Go To Checkout
Checkout
Screen.Checkout
CartPresenterCartView
Checkout
Screen.Checkout
CartPresenterCartView
Checkout
ScreenCreator
CartPresenterCartView
Creating(Screen.Checkout)
Checkout
ScreenCreator
CartPresenterCartView
Creating(Screen.Checkout)
Hidden CheckoutVIew
CartPresenterCartView
Screen.Checkout
ScreenCreator
CheckoutPresenter
CheckoutView
Hidden CheckoutVIew
CartPresenterCartView
Showing(Screen.Checkout)
ScreenCreator
CheckoutPresenter
CheckoutView
Hidden CheckoutVIew
CartPresenterCartView
Showing(Screen.Checkout)
ScreenCreator
CheckoutPresenter
CheckoutView
Hidden CheckoutVIew
CartPresenterCartView
Showing(Screen.Checkout)
ScreenCreator
CheckoutPresenter
CheckoutView
CheckoutView
With Data
CartPresenterCartView
Showing(Screen.Checkout)
ScreenCreator
CheckoutPresenter
CheckoutView
View tells presenter to go to new screen
presenter.openCart()
Presenter dispatches new screen state
sealed class Screen : State() {
data class Checkout(val payload:String) : Screen()
}
dispatcher.dispatch(Screen.Checkout)
Dispatcher encapsulates in a creating state
dispatcher.dispatch(Creating(Screen.Checkout))
Screen creator creates view/presenter
rxState.creating()
.subscribe({
createScreen(it)
})
Dispatches a showing state
rxState.creating()
.subscribe({
createScreen(it)
dispatcher.dispatch(Showing(it.screen))
})
Dispatcher adds each showing event to a back stack
override fun dispatch(state: State) {
when (state) {
is Showing->{
backstack.push(state)
rxState.push(state)
}
else -> rxState.push(state)
}
}
Dispatcher adds each showing event to a back stack
override fun dispatch(state: State) {
when (state) {
is Showing->{
backstack.push(state)
rxState.push(state)
}
else -> rxState.push(state)
}
}
val backstack: Stack<Showing> = Stack()
Dispatcher pushes new state to subscribers
override fun dispatch(state: State) {
when (state) {
is Showing->{
backstack.push(state)
rxState.push(state)
}
else -> rxState.push(state)
}
}
Presenter reacts to the showing state
override fun attachView(mvpView: CheckoutMVPView) {
rxState.showing(Screen.Checkout::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe { mvpView.show() }
Screens = States
sealed class Screen : State() {
object Search : Screen()
object Cart:Screen()
Data class Checkout(val items:List<Item>) : Screen()
data class Payment(val items:List<Item>) : Screen()
}
Routing becomes a state change
sealed class Screen : State() {
object Search : Screen()
object Cart:Screen()
Data class Checkout(val items:List<Item>) : Screen()
data class Payment(val items:List<Item>) : Screen()
}
fun goToSearch() {dispatcher.dispatch(Screen.Search)}
fun openCart() { dispatcher.dispatch(Screen.Cart) }
fun submitNames(firstName: String, lastName: String) {
userRepository.update(firstName, lastName)
.subscribe { dispatcher.dispatch(Screen.CheckoutPayment(cartItems)) }
}
Need to go back?
Dispatcher.goBack()
override fun onBackPressed() {
dispatcher.goBack()
}
interface Dispatcher {
fun dispatch(state: State)
fun goBack()
}
Dispatcher.goBack()
Dispatcher will pop current showing state and
dispatch previous one again
interface Dispatcher {
fun dispatch(state: State)
fun goBack()
}
override fun onBackPressed() {
dispatcher.goBack()
}
State Stack = Back Stack
override fun onBackPressed() {
dispatcher.goBack()
}
interface Dispatcher {
fun dispatch(state: State)
fun goBack()
}
Back Stack = State Stack
interface Dispatcher {
fun dispatch(state: State)
fun goBack()
}
override fun onBackPressed() {
dispatcher.goBack()
}
Routing becomes a state change
Every view interaction becomes a state change
Your UI becomes a representation
of dispatched state
Which is dispatched by your UI
TLDR: Your app becomes a cycle
TLDR: Your app becomes a cycle
User interacts with view
TLDR: Your app becomes a cycle
User interacts with view
View dispatches state change
TLDR: Your app becomes a cycle
User interacts with view
View dispatches state change
View reacts to state change
TLDR: Your app becomes a cycle
User interacts with view
View dispatches state change
View reacts to state change
User interacts with view
github.com/
digitalbuddha/Dispatcher
Big thank you to Efeturi
Money for the UI

More Related Content

Similar to Dispatching Reactive State

Double Loop
Double LoopDouble Loop
Double Loop
Jessica Mauerhan
 
Clean VIP (Clean Swift) architecture
Clean VIP (Clean Swift) architectureClean VIP (Clean Swift) architecture
Clean VIP (Clean Swift) architecture
Jianbin LIN
 
ReSwift & Machine Learning
ReSwift & Machine LearningReSwift & Machine Learning
ReSwift & Machine Learning
Rodrigo Leite
 
Ph d defense_Department of Information Technology, Uppsala University, Sweden
Ph d defense_Department of Information Technology, Uppsala University, SwedenPh d defense_Department of Information Technology, Uppsala University, Sweden
Ph d defense_Department of Information Technology, Uppsala University, Sweden
Sabesan Manivasakan
 
Four Steps Toward a Safer Continuous Delivery Practice (Hint: Add Monitoring)
Four Steps Toward a Safer Continuous Delivery Practice (Hint: Add Monitoring)Four Steps Toward a Safer Continuous Delivery Practice (Hint: Add Monitoring)
Four Steps Toward a Safer Continuous Delivery Practice (Hint: Add Monitoring)
VMware Tanzu
 
Reduxing UI: Borrowing the Best of Web to Make Android Better
Reduxing UI: Borrowing the Best of Web to Make Android BetterReduxing UI: Borrowing the Best of Web to Make Android Better
Reduxing UI: Borrowing the Best of Web to Make Android Better
Christina Lee
 
Chapter 4: Financial Statement Analysis
Chapter 4: Financial Statement AnalysisChapter 4: Financial Statement Analysis
Chapter 4: Financial Statement Analysis
Nada G.Youssef
 
Everything to Know About React Re-Rendering: A Comprehensive Guide
Everything to Know About React Re-Rendering: A Comprehensive GuideEverything to Know About React Re-Rendering: A Comprehensive Guide
Everything to Know About React Re-Rendering: A Comprehensive Guide
BOSC Tech Labs
 
Financial Statement Analysis
Financial Statement AnalysisFinancial Statement Analysis
Financial Statement Analysis
Faisal Hayat
 
Making design decisions in React-based ClojureScript web applications
Making design decisions in React-based ClojureScript web applicationsMaking design decisions in React-based ClojureScript web applications
Making design decisions in React-based ClojureScript web applications
Falko Riemenschneider
 
Rpt ppt
Rpt pptRpt ppt
Rpt ppt
sindhu T
 
Oracle business rules
Oracle business rulesOracle business rules
Oracle business rules
xavier john
 
ReactJs
ReactJsReactJs
Windows Phone 7 Unleashed Session 2
Windows Phone 7 Unleashed Session 2Windows Phone 7 Unleashed Session 2
Windows Phone 7 Unleashed Session 2
Wes Yanaga
 
Week 8
Week 8Week 8
Week 8
A VD
 
Whitepaper: Measuring Engagement in Native Advertising
Whitepaper:  Measuring Engagement in Native AdvertisingWhitepaper:  Measuring Engagement in Native Advertising
Whitepaper: Measuring Engagement in Native Advertising
Missy Steiner
 
Intuit's - Investor Day 2014 Presentation
Intuit's - Investor Day 2014 PresentationIntuit's - Investor Day 2014 Presentation
Intuit's - Investor Day 2014 Presentation
investorsintuitinc
 
Introduction To ReqPro
Introduction To ReqProIntroduction To ReqPro
Introduction To ReqPro
Leslie Munday
 
Build Restful Service using ADFBC
Build Restful Service using ADFBCBuild Restful Service using ADFBC
Build Restful Service using ADFBC
shravan kumar chelika
 

Similar to Dispatching Reactive State (20)

Double Loop
Double LoopDouble Loop
Double Loop
 
Clean VIP (Clean Swift) architecture
Clean VIP (Clean Swift) architectureClean VIP (Clean Swift) architecture
Clean VIP (Clean Swift) architecture
 
ReSwift & Machine Learning
ReSwift & Machine LearningReSwift & Machine Learning
ReSwift & Machine Learning
 
SEMrush 2
SEMrush 2SEMrush 2
SEMrush 2
 
Ph d defense_Department of Information Technology, Uppsala University, Sweden
Ph d defense_Department of Information Technology, Uppsala University, SwedenPh d defense_Department of Information Technology, Uppsala University, Sweden
Ph d defense_Department of Information Technology, Uppsala University, Sweden
 
Four Steps Toward a Safer Continuous Delivery Practice (Hint: Add Monitoring)
Four Steps Toward a Safer Continuous Delivery Practice (Hint: Add Monitoring)Four Steps Toward a Safer Continuous Delivery Practice (Hint: Add Monitoring)
Four Steps Toward a Safer Continuous Delivery Practice (Hint: Add Monitoring)
 
Reduxing UI: Borrowing the Best of Web to Make Android Better
Reduxing UI: Borrowing the Best of Web to Make Android BetterReduxing UI: Borrowing the Best of Web to Make Android Better
Reduxing UI: Borrowing the Best of Web to Make Android Better
 
Chapter 4: Financial Statement Analysis
Chapter 4: Financial Statement AnalysisChapter 4: Financial Statement Analysis
Chapter 4: Financial Statement Analysis
 
Everything to Know About React Re-Rendering: A Comprehensive Guide
Everything to Know About React Re-Rendering: A Comprehensive GuideEverything to Know About React Re-Rendering: A Comprehensive Guide
Everything to Know About React Re-Rendering: A Comprehensive Guide
 
Financial Statement Analysis
Financial Statement AnalysisFinancial Statement Analysis
Financial Statement Analysis
 
Making design decisions in React-based ClojureScript web applications
Making design decisions in React-based ClojureScript web applicationsMaking design decisions in React-based ClojureScript web applications
Making design decisions in React-based ClojureScript web applications
 
Rpt ppt
Rpt pptRpt ppt
Rpt ppt
 
Oracle business rules
Oracle business rulesOracle business rules
Oracle business rules
 
ReactJs
ReactJsReactJs
ReactJs
 
Windows Phone 7 Unleashed Session 2
Windows Phone 7 Unleashed Session 2Windows Phone 7 Unleashed Session 2
Windows Phone 7 Unleashed Session 2
 
Week 8
Week 8Week 8
Week 8
 
Whitepaper: Measuring Engagement in Native Advertising
Whitepaper:  Measuring Engagement in Native AdvertisingWhitepaper:  Measuring Engagement in Native Advertising
Whitepaper: Measuring Engagement in Native Advertising
 
Intuit's - Investor Day 2014 Presentation
Intuit's - Investor Day 2014 PresentationIntuit's - Investor Day 2014 Presentation
Intuit's - Investor Day 2014 Presentation
 
Introduction To ReqPro
Introduction To ReqProIntroduction To ReqPro
Introduction To ReqPro
 
Build Restful Service using ADFBC
Build Restful Service using ADFBCBuild Restful Service using ADFBC
Build Restful Service using ADFBC
 

More from Mike Nakhimovich

meetstore5.pdf
meetstore5.pdfmeetstore5.pdf
meetstore5.pdf
Mike Nakhimovich
 
Intro to GraphQL on Android with Apollo DroidconNYC 2017
Intro to GraphQL on Android with Apollo DroidconNYC 2017Intro to GraphQL on Android with Apollo DroidconNYC 2017
Intro to GraphQL on Android with Apollo DroidconNYC 2017
Mike Nakhimovich
 
Data Loading Made Easy with Mike Nakhimovich DroidCon Italy 2017
Data Loading Made Easy with Mike Nakhimovich DroidCon Italy 2017Data Loading Made Easy with Mike Nakhimovich DroidCon Italy 2017
Data Loading Made Easy with Mike Nakhimovich DroidCon Italy 2017
Mike Nakhimovich
 
Open sourcing the store
Open sourcing the storeOpen sourcing the store
Open sourcing the store
Mike Nakhimovich
 
Advanced Dagger talk from 360andev
Advanced Dagger talk from 360andevAdvanced Dagger talk from 360andev
Advanced Dagger talk from 360andev
Mike Nakhimovich
 
Sword fighting with Dagger GDG-NYC Jan 2016
 Sword fighting with Dagger GDG-NYC Jan 2016 Sword fighting with Dagger GDG-NYC Jan 2016
Sword fighting with Dagger GDG-NYC Jan 2016
Mike Nakhimovich
 
Intro to Functional Programming with RxJava
Intro to Functional Programming with RxJavaIntro to Functional Programming with RxJava
Intro to Functional Programming with RxJava
Mike Nakhimovich
 

More from Mike Nakhimovich (7)

meetstore5.pdf
meetstore5.pdfmeetstore5.pdf
meetstore5.pdf
 
Intro to GraphQL on Android with Apollo DroidconNYC 2017
Intro to GraphQL on Android with Apollo DroidconNYC 2017Intro to GraphQL on Android with Apollo DroidconNYC 2017
Intro to GraphQL on Android with Apollo DroidconNYC 2017
 
Data Loading Made Easy with Mike Nakhimovich DroidCon Italy 2017
Data Loading Made Easy with Mike Nakhimovich DroidCon Italy 2017Data Loading Made Easy with Mike Nakhimovich DroidCon Italy 2017
Data Loading Made Easy with Mike Nakhimovich DroidCon Italy 2017
 
Open sourcing the store
Open sourcing the storeOpen sourcing the store
Open sourcing the store
 
Advanced Dagger talk from 360andev
Advanced Dagger talk from 360andevAdvanced Dagger talk from 360andev
Advanced Dagger talk from 360andev
 
Sword fighting with Dagger GDG-NYC Jan 2016
 Sword fighting with Dagger GDG-NYC Jan 2016 Sword fighting with Dagger GDG-NYC Jan 2016
Sword fighting with Dagger GDG-NYC Jan 2016
 
Intro to Functional Programming with RxJava
Intro to Functional Programming with RxJavaIntro to Functional Programming with RxJava
Intro to Functional Programming with RxJava
 

Recently uploaded

May Marketo Masterclass, London MUG May 22 2024.pdf
May Marketo Masterclass, London MUG May 22 2024.pdfMay Marketo Masterclass, London MUG May 22 2024.pdf
May Marketo Masterclass, London MUG May 22 2024.pdf
Adele Miller
 
Quarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden ExtensionsQuarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden Extensions
Max Andersen
 
A Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of PassageA Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of Passage
Philip Schwarz
 
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
Alina Yurenko
 
Enterprise Resource Planning System in Telangana
Enterprise Resource Planning System in TelanganaEnterprise Resource Planning System in Telangana
Enterprise Resource Planning System in Telangana
NYGGS Automation Suite
 
openEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain SecurityopenEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain Security
Shane Coughlan
 
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing SuiteAI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
Google
 
Launch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in MinutesLaunch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in Minutes
Roshan Dwivedi
 
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI AppAI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
Google
 
Using Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional SafetyUsing Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional Safety
Ayan Halder
 
Graspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code AnalysisGraspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code Analysis
Aftab Hussain
 
Fundamentals of Programming and Language Processors
Fundamentals of Programming and Language ProcessorsFundamentals of Programming and Language Processors
Fundamentals of Programming and Language Processors
Rakesh Kumar R
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Neo4j
 
Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024
Paco van Beckhoven
 
AI Genie Review: World’s First Open AI WordPress Website Creator
AI Genie Review: World’s First Open AI WordPress Website CreatorAI Genie Review: World’s First Open AI WordPress Website Creator
AI Genie Review: World’s First Open AI WordPress Website Creator
Google
 
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdfVitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
Safe Software
 
Transform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR SolutionsTransform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR Solutions
TheSMSPoint
 
Mobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona InfotechMobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona Infotech
Drona Infotech
 
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxTop Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
rickgrimesss22
 

Recently uploaded (20)

May Marketo Masterclass, London MUG May 22 2024.pdf
May Marketo Masterclass, London MUG May 22 2024.pdfMay Marketo Masterclass, London MUG May 22 2024.pdf
May Marketo Masterclass, London MUG May 22 2024.pdf
 
Quarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden ExtensionsQuarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden Extensions
 
A Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of PassageA Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of Passage
 
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
 
Enterprise Resource Planning System in Telangana
Enterprise Resource Planning System in TelanganaEnterprise Resource Planning System in Telangana
Enterprise Resource Planning System in Telangana
 
openEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain SecurityopenEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain Security
 
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing SuiteAI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
 
Launch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in MinutesLaunch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in Minutes
 
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI AppAI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
 
Using Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional SafetyUsing Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional Safety
 
Graspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code AnalysisGraspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code Analysis
 
Fundamentals of Programming and Language Processors
Fundamentals of Programming and Language ProcessorsFundamentals of Programming and Language Processors
Fundamentals of Programming and Language Processors
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
 
Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024
 
AI Genie Review: World’s First Open AI WordPress Website Creator
AI Genie Review: World’s First Open AI WordPress Website CreatorAI Genie Review: World’s First Open AI WordPress Website Creator
AI Genie Review: World’s First Open AI WordPress Website Creator
 
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdfVitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdf
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
 
Transform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR SolutionsTransform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR Solutions
 
Mobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona InfotechMobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona Infotech
 
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxTop Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
 

Dispatching Reactive State