nytimes / Store

Android Library for Async Data Loading and Caching
Apache License 2.0
3.53k stars 305 forks source link

Having trouble fetching data using android nytimes store library #386

Closed thealmikey closed 5 years ago

thealmikey commented 5 years ago

Hi guys, I'm having an issue where my code which hits an API endpoint successfully from the fetcher doesn't update the persister. I'm using Android Room with StoreRoom

package com.example.myapplication.service.BlogService

import com.example.myapplication.model.Blog
import com.nytimes.android.external.store3.base.Fetcher
import com.nytimes.android.external.store3.base.impl.BarCode
import com.nytimes.android.external.store3.base.impl.MemoryPolicy
import com.nytimes.android.external.store3.base.impl.StalePolicy
import com.nytimes.android.external.store3.base.impl.room.StoreRoom
import com.nytimes.android.external.store3.base.room.RoomPersister
import io.reactivex.Observable
import java.util.concurrent.TimeUnit

class BlogStore(val blogRemoteService: BlogRemoteService, val blogLocalService: BlogLocalService) {

    var fetcher = Fetcher<List<Blog>, BarCode> {
        blogRemoteService.fetchBlogs()
    }

    val persister = object : RoomPersister<List<Blog>, List<Blog>, BarCode> {

        override fun read(barCode: BarCode): Observable<List<Blog>> {
            return blogLocalService.fetchAll().toObservable()
        }

        override fun write(barCode: BarCode, blogList: List<Blog>) {
            blogLocalService.addBlogs(blogList)
        }
    }

    var memoryPolicy: MemoryPolicy = MemoryPolicy
        .builder()
        .setExpireAfterWrite(5)
        .setExpireAfterTimeUnit(TimeUnit.SECONDS)
        .build()

    var store = StoreRoom.from(fetcher, persister, StalePolicy.REFRESH_ON_STALE, memoryPolicy)

    fun getBlogs(): Observable<List<Blog>> {
        store.clear()
        return store.fetch(BarCode.empty())
    }
}

calls to getBlogs() above don't get data from the server, only fetch data locally stored ,whereas calls to blogRemoteService.fetchBlogs() in my Fetcher successfully return Single<List<Blog>>,

thealmikey commented 5 years ago

I found out the solution to my problem, in my RoomPersister in the write method i was passing blogLocalService.addBlogs(blogList) which returns a Single<List<Blog>> . This is what i had previously

val persister = object : RoomPersister<List<Blog>, List<Blog>, BarCode> {

        override fun read(barCode: BarCode): Observable<List<Blog>> {
            return blogLocalService.fetchAll().toObservable()
        }

        override fun write(barCode: BarCode, blogList: List<Blog>) {
            blogLocalService.addBlogs(blogList)
        }
    }

I wrongly assumed that the Singe<List<Blog>>> method would somehow automatically get subscribbed to. This was my final code that worked

val persister = object : RoomPersister<List<Blog>, List<Blog>, BarCode> {

        override fun read(barCode: BarCode): Observable<List<Blog>> {
            return blogLocalService.fetchAll().toObservable()
        }

        override fun write(barCode: BarCode, blogList: List<Blog>) {
            blogLocalService.addBlogs(blogList).
            .subscribeOn(Schedulers.io())
                    .observeOn(Schedulers.io())
                    .subscribe({
                    Log.d("BlogLocalService","successful write to db")
                },{
                    Log.d("BlogLocalService","failed to write to db with error: ${it.message}")
                })
        }
    }