Reputation: 6697
I'm using Retrofit to get bookmarks from REST API:
public interface BookmarkService {
@GET("/bookmarks")
Observable<List<Bookmark>> bookmarks();
}
Now I would like to emit each item from this list with delay.
I did something similar to this in Java, but onCompleted
is never triggered.
private Observable<Bookmark> getBookmarks() {
return getBookmarkService().bookmarks()
.flatMap(new Func1<List<Bookmark>, Observable<Bookmark>>() {
@Override
public Observable<Bookmark> call(List<Bookmark> bookmarks) {
Observable<Bookmark> resultObservable = Observable.never();
for (int i = 0; i < bookmarks.size(); i++) {
List<Bookmark> chunk = bookmarks.subList(i, (i + 1));
resultObservable = resultObservable.mergeWith(Observable.from(chunk).delay(1000 * i, TimeUnit.MILLISECONDS));
}
return resultObservable;
}
})
.observeOn(AndroidSchedulers.mainThread());
}
What I'm doing wrong?
Usage:
mSwipeRefreshLayout.setRefreshing(true);
getBookmarks()
.subscribe(new Observer<Bookmark>() {
@Override
public void onCompleted() {
Timber.i("Completed");
mSwipeRefreshLayout.setRefreshing(false);
}
@Override
public void onError(Throwable e) {
Timber.i("Error: %s", e.toString());
mSwipeRefreshLayout.setRefreshing(false);
}
@Override
public void onNext(Bookmark bookmark) {
Timber.i("Bookmark: %s", bookmark.toString());
mBookmarksAdapter.addItem(bookmark);
}
});
Upvotes: 7
Views: 5467
Reputation: 11515
As you use a merge operation, onCompleted will be call if all Observables are completed. but Observable.never()
will never complete. Use Observable.empty()
instead.
According to your code, your want to emit sublist with delay. The sublist contains only one element
What you can do : flatmap your list, to emit each items. Buffer it to build a list from items, then use a delay.
private Observable<Bookmark> getBookmarks() {
return getBookmarkService().bookmarks()
.flatMap((bookmarks) -> Observable.from(bookmarks)
.buffer(1)
.scan(new Pair(0, null), (ac, value) -> new Pair(acu.index + 1, value)
.flatMap(pair -> Observable.just(pair.value).delay(pair.index, SECONDS))
.observeOn(AndroidSchedulers.mainThread());
}
it might work (not tested)
Upvotes: 4