Last active
July 14, 2020 14:23
-
-
Save peterpazmandi/b28e53b702e9bb83978d5e84b0d125a6 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fun observeSet(id: String) = resultLiveData( | |
databaseQuery = { dao.getLegoSet(id) }, | |
networkCall = { legoSetRemoteDataSource.fetchSet(id) }, | |
saveCallResult = { dao.insert(it) }) | |
/** | |
* Creates a new [LiveData] object does not emit a value until the source `this` LiveData value | |
* has been changed. The value is considered changed if `equals()` yields `false`. | |
*/ | |
.distinctUntilChanged() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
data class Result<out T>(val status: Status, val data: T?, val message: String?) | |
{ | |
enum class Status | |
{ | |
SUCCESS, | |
ERROR, | |
LOADING | |
} | |
companion object | |
{ | |
fun <T> success(data: T): Result<T> | |
{ | |
return Result(Status.SUCCESS, data, null) | |
} | |
fun <T> error(message: String, data: T? = null): Result<T> | |
{ | |
return Result(Status.ERROR, data, message) | |
} | |
fun <T> loading(data: T? = null): Result<T> | |
{ | |
return Result(Status.LOADING, data, null) | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import androidx.lifecycle.ViewModel | |
import com.elifox.legocatalog.legoset.data.LegoSetRepository | |
import javax.inject.Inject | |
/** | |
* The ViewModel used in [SetFragment]. | |
*/ | |
class LegoSetViewModel @Inject constructor(repository: LegoSetRepository) : ViewModel() | |
{ | |
lateinit var id: String | |
val legoSet by lazy { repository.observeSet(id) } | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import androidx.lifecycle.LiveData | |
import androidx.lifecycle.liveData | |
import androidx.lifecycle.map | |
import com.elifox.legocatalog.data.Result.Status.ERROR | |
import com.elifox.legocatalog.data.Result.Status.SUCCESS | |
import kotlinx.coroutines.Dispatchers | |
/** | |
* The database serves as the single source of truth. | |
* Therefore UI can receive data updates from database only. | |
* Function notify UI about: | |
* [Result.Status.SUCCESS] - with data from database | |
* [Result.Status.ERROR] - if error has occurred from any source | |
* [Result.Status.LOADING] | |
*/ | |
fun <T, A> resultLiveData(databaseQuery: () -> LiveData<T>, | |
networkCall: suspend () -> Result<A>, | |
saveCallResult: suspend (A) -> Unit): LiveData<Result<T>> = | |
liveData(Dispatchers.IO) { | |
emit(Result.loading<T>()) | |
val source = databaseQuery.invoke().map { Result.success(it) } | |
emitSource(source) | |
val responseStatus = networkCall.invoke() | |
if (responseStatus.status == SUCCESS) | |
{ | |
saveCallResult(responseStatus.data!!) | |
} | |
else if (responseStatus.status == ERROR) | |
{ | |
emit(Result.error<T>(responseStatus.message!!)) | |
emitSource(source) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment