sockeqwe / mosby

A Model-View-Presenter / Model-View-Intent library for modern Android apps
http://hannesdorfmann.com/mosby/
Apache License 2.0
5.49k stars 841 forks source link

Problem with most basic sample project #206

Closed asyncee closed 7 years ago

asyncee commented 7 years ago

Hello, Hannes!

I'm struck with the problem — i wrote a most basic sample project (it is almost copy-paste), launched it and... nothing happened. Let me show a code:

FeedView.java

public interface FeedView extends MvpView {
    Observable<Boolean> loadFirstPageIntent();
    void render(FeedViewState viewState);
}
FeedActivity.java

public class FeedActivity extends MviActivity<FeedView, FeedPresenter> implements FeedView {

    @NonNull
    @Override
    public FeedPresenter createPresenter() {
        return new FeedPresenter();
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_feed);
    }

    @Override
    public Observable<Boolean> loadFirstPageIntent() {
        return Observable.just(true).doOnComplete(() -> Timber.d("firstPage completed"));
    }

    @Override
    public void render(FeedViewState viewState) {
        Timber.d("rendering view state", viewState);
        if (viewState.isLoadingFirstPage()) {
            renderLoadingFirstPage();
        } else if (viewState.getLoadingFirstPageError() != null) {
            renderLoadingFirstPageError();
        } else if (!viewState.isLoadingFirstPage() && viewState.getLoadingFirstPageError() == null) {
            renderFeedData(viewState.getData());
        } else {
            throw new IllegalStateException("Unknown view state " + viewState);
        }
    }

    private void renderLoadingFirstPageError() {
        Timber.d("loading first page error");
    }

    private void renderLoadingFirstPage() {
        Timber.d("curently loading first page");
    }

    private void renderFeedData(List<FeedItem> data) {
        Timber.d("rendering data", data);
    }
}
FeedPresenter.java

public class FeedPresenter extends MviBasePresenter<FeedView, FeedViewState> {
    private final FeedLoader feedLoader = new FeedLoader();

    @Override
    protected void bindIntents() {
        Timber.d("bind intents");
        List<FeedItem> emptyList = Collections.emptyList();

        Observable<FeedViewState> loadFirstPage = intent(FeedView::loadFirstPageIntent)
                .doOnNext(aBoolean -> Timber.d("intent: load first page"))
                .flatMap(ignored -> feedLoader.loadFirstPage())
                .map(items -> new FeedViewState(false, null, items))
                .startWith(items -> new FeedViewState(true, null, emptyList))
                .onErrorReturn(error -> new FeedViewState(false, error, emptyList))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());

        subscribeViewState(loadFirstPage, FeedView::render);
    }
}

All i get in log is:

FeedPresenter: bind intents FeedActivity: FirstPage completed

and that's all — there are no logs from FeedView::render method (and also .doOnNext(aBoolean -> Timber.d("intent: load first page")) is not executed, too).

I triple-checked my sources, your sources, your articles and still can not find the problem, the code looks 1:1 similar.

It would be great if you can spend a little time to help me find the bug.

Software versions:

// rxjava
    compile 'io.reactivex.rxjava2:rxjava:2.0.4'
    compile 'io.reactivex.rxjava2:rxandroid:2.0.1'

    // butterknife
    compile 'com.jakewharton:butterknife:8.4.0'
    annotationProcessor 'com.jakewharton:butterknife-compiler:8.4.0'

    // mosby
    compile 'com.hannesdorfmann.mosby3:mvp:3.0.0-alpha3'
    compile 'com.hannesdorfmann.mosby3:viewstate:3.0.0-alpha3'
    compile 'com.hannesdorfmann.mosby3:mvi:3.0.0-alpha3'

    // timber
    compile 'com.jakewharton.timber:timber:4.5.1'

Thanks!

sockeqwe commented 7 years ago

Hi, In your presenter's bindIntent() method you are using the startWith() incorrect You you should use .startWith(new FeedItem(...)) rather than startWith(items -> new FeedViewState(...)) (the later one is never emitting an item).

Btw. you just need to include

compile 'com.hannesdorfmann.mosby3:mvi:3.0.0-alpha3'

in your dependencies. The others are not required with MVI

asyncee commented 7 years ago

Oh, thank you, Hannes! What a silly typo. I'm confused, why i did not noticed it earlier. Now it is working. Have a nice day! ;)