Wednesday 10 March 2021

Save remote data separately related tables when using NetworkBoundRepository with coroutines (android)

I want to use Single source of truth principle in my application. How can I add multiple table when using NetworkBoundRepository.

MainApi.kt

interface MainApi {
    @GET("main")
    suspend fun getMain(): Response<MainResponse>
}

MainResponse.kt

@JsonClass(generateAdapter = true)
data class MainResponse(
        @Json(name = "categories") val categoryList: List<Category>,
        @Json(name = "locations") val locationList: List<Location>,
        @Json(name = "tags") val tagList: List<Tag>
) 

NetworkBoundRepository.kt

@ExperimentalCoroutinesApi
abstract class NetworkBoundRepository<RESULT, REQUEST> {

    fun asFlow() = flow<Resource<RESULT>> {
        emit(Resource.Success(fetchFromLocal().first()))
        val apiResponse = fetchFromRemote()
        val remoteCategories = apiResponse.body()

        if (apiResponse.isSuccessful && remoteCategories != null) {
            saveRemoteData(remoteCategories)
        } else {
            emit(Resource.Failed(apiResponse.message()))
        }

        emitAll(
            fetchFromLocal().map {
                Resource.Success<RESULT>(it)
            }
        )
    }.catch { e ->
        emit(Resource.Failed("Network error! Can't get latest categories."))
    }

    @WorkerThread
    protected abstract suspend fun saveRemoteData(response: REQUEST)

    @MainThread
    protected abstract fun fetchFromLocal(): Flow<RESULT>

    @MainThread
    protected abstract suspend fun fetchFromRemote(): Response<REQUEST>
}

MainRepository.kt

@ExperimentalCoroutinesApi
class MainRepository @Inject constructor(
    private val mainApi: MainApi,
    private val categoryDao: CategoryDao,
    private val locationDao: LocationDao,
    private val tagDao: TagDao
) {
        suspend fun getMain(): Flow<Resource<List<Category>>> {
        return object : NetworkBoundRepository<List<Category>, List<Category>>() {
            override suspend fun saveRemoteData(response: List<Category>) = categoryDao.insertList(response)
            override fun fetchFromLocal(): Flow<List<Category>> = categoryDao.getList()
            override suspend fun fetchFromRemote(): Response<List<Category>> = mainApi.getMain()
        }.asFlow()
    }
}

Currently NetworkBoundRepository and MainRepository only works with categories. I want to fetch some data from internet and save each data to related tables in database. App must be offline first. How can I add locationDao, tagDao to MainRepository?



from Save remote data separately related tables when using NetworkBoundRepository with coroutines (android)

No comments:

Post a Comment