I’m trying to figure out how to apply functional programming to a feature I’m writing in an Android app. After reading The introduction to Reactive Programming you've been missing, Retrofit and RxJava, Android multi-threaded REST requests, and Why you should use RxJava in Android a short introduction to RxJava, reactive programming seems like a great fit for this feature.
Scenario:
- User taps on settings
- A list is populated with a set of values cached (on disk) from REST API calls
- User can refresh the cache by clicking a refresh button
To obtain the values from the REST API calls, there are two phases:
- API1 - returns ids (requires two HTTP request headers, “Date” and “Authorization" for authentication)
- API2 - given an id, returns details about that id (no authentication)
Since I’m new to reactive programming, I think I should start by writing the pseudo-code in a reactive programming style. Then I’ve got to translate the pseudo-code into actual Java code appropriate for Android. To do that I will need to know which are the best reactive programming libraries to apply for my task.
To begin writing the pseudo-code, I’ll use the syntax @andré-staltz uses in The introduction to Reactive Programming you've been missing:
User_Actions:
-i-----------i---------------> screen_initialization: user goes into screen
-N-----------Y---------------> check_cache: map() gives N if data not found in db, Y otherwise
-q---------------------------> do_refresh_cache1: filter() out anything by N
----------------r------------> refresh_button_clicks
-q--------------r------------> do_refresh_cache2: merge() streams screen_initialization and do_refresh_cache1
Caching:
-q--------------r------------> clear_cache: map() do_refresh_cache2, clearing datBAase
-cba|-----------cbad|--------> get_ids: flatMap() call API1 for ids (e.g. q results in 3 ids: a, b, c)
-CBA|-----------CBAD|--------> get_details: map() calls API2 for each id to get details
-CBA|-----------CBAD|--------> persist: map() persists each value (A, B, C, etc.) in the datBAase cache
----P---------------P--------> emit_ready: toPromise() emits a signal when we have details for each id
Loading:
-q--------------r------------> do_load_from_cache: merge() streams screen_initialization and do_refresh_cache1
----P---------------P--------> wait_for_ready: fromPromise() waits for a signal when we have details for each id
----CBA|------------CBAD|----> load_from_cache: flatMap() query database for id details when wait_for_ready promise fullfilled
-------ABC|-------------ABCD|> display: somehow sort the results
UI:
-s--------------s------------> show_spinner: map() do_refresh_cache2 to show a spinner while making network calls
----------h-----------------h> hide_spinner: hide spinner when display stream finishes
Questions:
- Psuedo-code: How do I make my psuedo-code match the requirements?
- Real code: Which methods in RxJava, RxAndroid, or some other reactive programming library should to convert the psuedo-code into real code for Android?