Having read the article MODEL-VIEW-INTENT written by Hannes Dorfmann, I designed my app using the MVI pattern.
This is my design chart of my application.
I have two reusable fragments, BarFragment and ContentFragment. And my activity is made up of those two fragments.
The data flow is:
Step 1: The changeKeywordIntent() method gathers user's input from the search view in BarFragment.
override fun changeKeywordIntent(): Observable<String?> {
return RxSearchView.queryTextChangeEvents(view!!.search)
.filter { it.isSubmitted }
.map { it.queryText().toString() }
}
Step 2: To reuse the fragment, the intent is not subscribed by render() method directly.
On receiving the intent, the presenter emit an PartialViewState.ChangeKeyword(keyword) object to the partialViewStateSubject first. This partial view state will be reduced to ViewState and then, consumed by all the MvpView's render() method. I.E., the views will show that keyword at a proper position.
This is like a broadcast.
After the PartialViewState.ChangeKeyword(keyword) object has been rendered, the presenter calls a business logic and then emit a PartialViewState.ContentFirstPage(response.body()) start with a PartialViewState.Loading() object.
My question is in this step, Call which RxJava2 method can I ensure that before the second observable emit, the first observable is subscribed? And which method to create the second observable?
intent(EmployeesBarView::changeKeywordIntent).flatMap { keyword ->
Observable.concat(
Observable.just(EmployeesScenarioPartialViewState.ChangeKeyword(keyword) as EmployeesScenarioPartialViewState),
Observable.someMethod {
// to ensure viewStateSubject.value is the value after PartialViewState.ChangeKeyword(keyword) has been subscribed, I don't know which method I should call
Observable.just(viewStateSubject.value).flatMap { viewState ->
EmployeeStub.getInstance(activity.baseContext).query(toFilterLogicExpr(viewState.keyword), toOrderByListExpr(viewState.orderBy), toRangeExpr(0, viewState.pageSize), null).toObservable()
.map { response -> EmployeesScenarioPartialViewState.ContentFirstPage(response.body()) as EmployeesScenarioPartialViewState }
.startWith(EmployeesScenarioPartialViewState.Loading())
.onErrorReturn { error -> EmployeesScenarioPartialViewState.Error(error.message) }
}
})
}.subscribe(partialViewStateSubject::onNext).addTo(compositeDisposable)
Step 3: When a PartialViewState object is received, reduce it to a ViewState object and push the ViewState object to viewStateSubject. Key code is
employeesScenarioViewStatePartialSubject
.scan(initialEmployeesScenarioViewState(), ::reduceEmployeesScenarioViewState)
.subscribe(employeesScenarioViewStateSubject::onNext)
.addTo(compositeDisposable)
Step 4: All presenters subscribe viewStateSubject in bindIntents() method
subscribeViewState(viewStateSubject.observeOn(AndroidSchedulers.mainThread())) { obj, state -> obj.render(state) }
Step 5: render the viewState object, the code could be skipped in this question.
So my question is in step 2, could anyone help me with that code with RxJava2? Thank you.