{"action":"created","issue":{"url":"https://api.github.com/repos/sockeqwe/mosby/issues/130","repository_url":"https://api.github.com/repos/sockeqwe/mosby","labels_url":"https://api.github.com/repos/sockeqwe/mosby/issues/130/labels{/name}","comments_url":"https://api.github.com/repos/sockeqwe/mosby/issues/130/comments","events_url":"https://api.github.com/repos/sockeqwe/mosby/issues/130/events","html_url":"https://github.com/sockeqwe/mosby/issues/130","id":148073889,"number":130,"title":"Handling cached data in Mosby with RxJava","user":{"login":"fdorssers","id":5364280,"avatar_url":"https://avatars.githubusercontent.com/u/5364280?v=3","gravatar_id":"","url":"https://api.github.com/users/fdorssers","html_url":"https://github.com/fdorssers","followers_url":"https://api.github.com/users/fdorssers/followers","following_url":"https://api.github.com/users/fdorssers/following{/other_user}","gists_url":"https://api.github.com/users/fdorssers/gists{/gist_id}","starred_url":"https://api.github.com/users/fdorssers/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fdorssers/subscriptions","organizations_url":"https://api.github.com/users/fdorssers/orgs","repos_url":"https://api.github.com/users/fdorssers/repos","events_url":"https://api.github.com/users/fdorssers/events{/privacy}","received_events_url":"https://api.github.com/users/fdorssers/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2016-04-13T14:09:35Z","updated_at":"2016-04-13T14:47:13Z","closed_at":"2016-04-13T14:47:13Z","body":"This isn't as much as an issue as it is a question, but I'm wondering if you have a suggestion on how to handle and show cached data using RxJava in Mosby.\r\n\r\nI'll use the `sample-dagger2-rx` module as example. This contains `ReposPresenter` which extends `MvpLceRxPresenter`. This presenter uses `.setData(data)` on the view in `.onNext(data)` and then actually makes this visible in `.onCompleted()` with `.showContent()`. However in this case you would always have to wait for the API call to GitHub to finish. This means that if I've just loaded the repos, closed the app, disabled internet, and loaded the app back up, it would give me the error screen because it can't get any data. However I'd like it to be able to show previously stored data.\r\n\r\nSo lets wrap this call in a model, interactor, or whatever it's called in MVP:\r\n\r\n```Java\r\npublic class RepoModel {\r\n\tpublic Observable<Repo> getRepos(boolean useCache) {\r\n\t\tObservable<List<Repo>> api = githubApi.getRepos();\r\n\t\tif (!useCache) {\r\n\t\t\treturn api;\r\n\t\t}\r\n\t\tObservable<List<Repo>> local = githubSql.getRepos();\r\n\t\treturn Observable.concat(local, api);\r\n\t}\r\n}\r\n```\r\nAnd use it in the presenter:\r\n```Java\r\npublic void loadRepos(boolean pullToRefresh) {\r\n\tObservable<List<Repo>> observable = repoModel.getRepos(!pullToRefresh);\r\n\tsubscribe(observable, pullToRefresh);\r\n}\r\n```\r\n\r\nThis is just a simple representation, omitting storing of the response, etc. In this case the `.getRepos(useCache)` call on the model gives us an observable which will call `.onNext(data)` twice if we use the cache (if we don't use pull to refresh), once with the local data and once with the api data. But `.onCompleted()` won't be called until the observable is finished, so the first `.onNext(data)` will never be visible. \r\n\r\nSo I could solve this by changing `.onNext(data)` and `.onCompleted()` to the following:\r\n```Java\r\nprotected void onNext(M data) {\r\n    if (isViewAttached()) {\r\n        getView().setData(data);\r\n        getView().showContent();\r\n    }\r\n}\r\n```\r\nAnd:\r\n```Java\r\nprotected void onCompleted() {\r\n    unsubscribe();\r\n}\r\n```\r\nThis way `.onNext(data)` will also show the content in each call and `.onCompleted()` will only unsubscribe. Obviously this still leaves some other small things, like changing `.onError()` to only show a full screen error if we haven't ever cached any data yet, otherwise we can always show the small error (toast, snackbar, whatever), that's also used for a pull to refresh error. \r\n\r\nAnyway, I'm wondering what your take on this is. Maybe you see something I'm missing, or maybe you'd do it in a completely different way within Mosby."},"comment":{"url":"https://api.github.com/repos/sockeqwe/mosby/issues/comments/209484187","html_url":"https://github.com/sockeqwe/mosby/issues/130#issuecomment-209484187","issue_url":"https://api.github.com/repos/sockeqwe/mosby/issues/130","id":209484187,"user":{"login":"sockeqwe","id":583598,"avatar_url":"https://avatars.githubusercontent.com/u/583598?v=3","gravatar_id":"","url":"https://api.github.com/users/sockeqwe","html_url":"https://github.com/sockeqwe","followers_url":"https://api.github.com/users/sockeqwe/followers","following_url":"https://api.github.com/users/sockeqwe/following{/other_user}","gists_url":"https://api.github.com/users/sockeqwe/gists{/gist_id}","starred_url":"https://api.github.com/users/sockeqwe/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sockeqwe/subscriptions","organizations_url":"https://api.github.com/users/sockeqwe/orgs","repos_url":"https://api.github.com/users/sockeqwe/repos","events_url":"https://api.github.com/users/sockeqwe/events{/privacy}","received_events_url":"https://api.github.com/users/sockeqwe/received_events","type":"User","site_admin":false},"created_at":"2016-04-13T14:47:13Z","updated_at":"2016-04-13T14:47:13Z","body":"The way you are doing it is correct. Mosby doesn't specify anything about RxJava or how to handle subscription callbacks like `onNext()`, `onError()` and `onCompleted()`.\r\n\r\nSo in your case doing something like \r\n\r\n```java\r\nprotected void onNext(M data) {\r\n    if (isViewAttached()) {\r\n        getView().setData(data);\r\n        getView().showContent();\r\n    }\r\n}\r\n```\r\n\r\nsounds reasonable if your `onNext()` gets called multiple times.\r\nActually, that is the reason why there is no build in `MvpLceRxPresenter` in Mosby because I can't provide a presenter class to extend from for all different kind of use cases.\r\n\r\nSo yes, go ahead and write your own Presenter (or rx subscriber) that fits for your use case.\r\nIf you find the interaction between view and presenter too complex than probably LceView is not the right choice for you. Then you should think about writing your own View Interface with those method you exactly need.\r\n\r\nRegarding error handling (again it's not Mosby related, it's RxJava related) you might not want to call `onError()` if you an networking or cache error (or not available) occurs. You can use other rx java operators like `onErrorResumeNext()` or `onErrorReturn()` etc. which can be applied on cacheable observable and networking observable to control the overall observable flow in case of errors.\r\nAdditionally, if your View needs to distinguish between cache or network `onNext()` you could also think about delivering the result in a wrapper class like this:\r\n```java\r\nclass Result {  \r\n  Repo result;\r\n  boolean fromCache;\r\n}\r\n```\r\nand then Presenter subscribes to `Observable<Result>` rather than `Observable<Repo>` (so also your `onNext(Observable<Result>)` contains the info if coming from cache or network).\r\n\r\nAlso, if you are using retrofit you can override caching headers to force retrofit to always hit the disk cache first (and deliver result in `onNext()` ), and then continue with the real network request which then triggers again `onNext()`.\r\n"}}