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

Single screen with multiple requests with different responses #155

Closed atetc closed 8 years ago

atetc commented 8 years ago

I want to implement this case using Mosby 2 and I found one approach. Please check my solution:

Model (wrapper of different type of response objects):

public class ListModel {
    ResponseType responseType;

    List<Item> list;
    ItemDetails removedItemDetails;
    Congrats congrats;

    public ListModel(ResponseType responseType, Object object) {
        this.responseType = responseType;
        setModelObject(object);
    }

    private void setModelObject(Object object) {
        switch (responseType) {
            case REMOVE:
                removedItemDetails = (ItemDetails) object;
                break;
            case ADD:
                congrats = (Congrats) object;
                break;
            case LIST:
            default:
                list = (List<Item>) object;
    }

    enum ResponseType {
        LIST,
        ADD,
        REMOVE
    }
}

Requests:

subscribe(repository.getList()
                    .map(list -> new ListModel(ResponseType.LIST, list), false);

subscribe(repository.remove(id)
                    .map(itemDetails -> new ListModel(ResponseType.REMOVE, itemDetails))
                    .onErrorResumeNext(throwable -> Observable.error(new ListItemRemoveException(throwable))), true);

subscribe(repository.add()
                    .map(congrats -> new ListModel(ResponseType.ADD, congrats))
                    .onErrorResumeNext(throwable -> Observable.error(new ListItemAddException(throwable))), true);

Handling:

@Override
    protected void onNext(Model data) {
        if (data.responseType == ResponseType.REMOVE) {
            getView().onItemRemoved(data.removedItem);
        } else if (data.responseType == ResponseType.ADD) {
            getView().onItemAdded(data.congrats);
        } else {
            super.onNext(data);
        }
    }

@Override
    protected void onError(Throwable e, boolean pullToRefresh) {
        if (e instanceof ListItemRemoveException) {
            getView().onRemoveItemError(e);
        } else if (e instanceof ListItemAddException) {
            getView().onAddItemError(e);
        } else {
            super.onError(e, pullToRefresh);
        }
    }
sockeqwe commented 8 years ago

Seems like a valid option to me ...