oldergod / android-architecture

MVI architecture Implementation of the ToDo app.
Apache License 2.0
669 stars 70 forks source link

[q] Access state in stream #27

Closed j-garin closed 6 years ago

j-garin commented 6 years ago

Hello. Thank you for this wonderful demo project. It does clear up things a lot.

I have the following task: i have paginated data + search functionality that is done on backend. So every time the search text changes, i put it into the state object and all data load requests will take that search string as a parameter. My question is whether i can somehow read that search string value from current state when transforming intents into actions? What is a good way of doing it?

I am thinking of using a BehaviorSubject for state as a separate stream that the original stream will push data to from subscribe(). But it looks kinda ugly and i wanted to figure out a good way of doing it.

oldergod commented 6 years ago

You can see how I do it in another project here: https://github.com/oldergod/red/blob/develop/app/src/main/java/com/benoitquenaudon/tvfoot/red/app/domain/matches/MatchesIntent.kt#L30

Basically, when the text changes, a new intent is emitted and then it follows the flow normally like other events do.

j-garin commented 6 years ago

@oldergod Thank you for your answer. I've checked it out and it turn out that iworkflow is quite different.

My api returns paginated data for search. So speaking in terms of MVVI my SearchIntent(searchText) is transformed into a LoadDataAction(searchText = searchText, forceRefresh = true, page = 0). To load the next page of search results, i need to provide the same searchText with a different page index. I have the searchText saved in the state object. I need this when transforming NexPageIntent -> LoadDataAction. What is a good way of getting it? Passing it from UI every time a user wants to load next page of data doesn't sound like a good way to me, because i already have it in our state object.

oldergod commented 6 years ago

Say you have searchTextChanges(): Observable<String> which emits searchText and reachedBottom(): Observable<Integer> which emits page. You could create a stream with combineLatest(searchTextChanges(), reachedBottom()) and so, for every emitted event, you could create a SearchIntent that would take both those values into account?

j-garin commented 6 years ago

@oldergod thank you! this solution is so simple now i feel embarrassed for not noticing it earlier

oldergod commented 6 years ago

Glad you found a solution!