From 3a29504fd2f472fc2bb3f43921eda3f85c6ec7bd Mon Sep 17 00:00:00 2001 From: Carlos Martinez Date: Thu, 17 Jun 2021 12:08:48 -0400 Subject: [PATCH] Add: viewmodel --- .../main/res/xml/network_security_config.xml | 2 +- .../core/domain/network/NetworkErrors.kt | 7 ++++ .../core/domain/network/RequestState.kt | 3 +- .../dev/carlos/core/viewmodel/RxViewModel.kt | 17 +++++++++ .../shortform/data/AcronymsDataRepository.kt | 2 +- .../dev/carlos/shortform/di/AcronymsModule.kt | 4 ++ .../shortform/viewmodels/AcronymsViewmodel.kt | 37 +++++++++++++++++++ 7 files changed, 69 insertions(+), 3 deletions(-) create mode 100644 core/src/main/java/dev/carlos/core/domain/network/NetworkErrors.kt create mode 100644 core/src/main/java/dev/carlos/core/viewmodel/RxViewModel.kt create mode 100644 shortform/src/main/java/dev/carlos/shortform/viewmodels/AcronymsViewmodel.kt diff --git a/app/src/main/res/xml/network_security_config.xml b/app/src/main/res/xml/network_security_config.xml index 8b6c476..754ccf0 100644 --- a/app/src/main/res/xml/network_security_config.xml +++ b/app/src/main/res/xml/network_security_config.xml @@ -3,4 +3,4 @@ www.nactem.ac.uk - \ No newline at end of file + diff --git a/core/src/main/java/dev/carlos/core/domain/network/NetworkErrors.kt b/core/src/main/java/dev/carlos/core/domain/network/NetworkErrors.kt new file mode 100644 index 0000000..83e931f --- /dev/null +++ b/core/src/main/java/dev/carlos/core/domain/network/NetworkErrors.kt @@ -0,0 +1,7 @@ +package dev.carlos.core.domain.network + +enum class RequestError { + NO_NETWORK, + BAD_RESPONSE, + UNKNOWN_PROBLEM +} diff --git a/core/src/main/java/dev/carlos/core/domain/network/RequestState.kt b/core/src/main/java/dev/carlos/core/domain/network/RequestState.kt index 956f293..b710558 100644 --- a/core/src/main/java/dev/carlos/core/domain/network/RequestState.kt +++ b/core/src/main/java/dev/carlos/core/domain/network/RequestState.kt @@ -3,5 +3,6 @@ package dev.carlos.core.domain.network sealed class RequestState { class Success(val data: T) : RequestState() object Loading : RequestState() - class Error(val throwable: Throwable) : RequestState() + class Error(val type: RequestError) : RequestState() + object Empty : RequestState() } diff --git a/core/src/main/java/dev/carlos/core/viewmodel/RxViewModel.kt b/core/src/main/java/dev/carlos/core/viewmodel/RxViewModel.kt new file mode 100644 index 0000000..d6a8e8b --- /dev/null +++ b/core/src/main/java/dev/carlos/core/viewmodel/RxViewModel.kt @@ -0,0 +1,17 @@ +package dev.carlos.core.viewmodel + +import androidx.lifecycle.ViewModel +import io.reactivex.disposables.CompositeDisposable + +abstract class RxViewModel : ViewModel() { + protected val compositeDisposable by lazy { CompositeDisposable() } + + override fun onCleared() { + super.onCleared() + clearCompositeDisposable() + } + + private fun clearCompositeDisposable() { + compositeDisposable.clear() + } +} diff --git a/shortform/src/main/java/dev/carlos/shortform/data/AcronymsDataRepository.kt b/shortform/src/main/java/dev/carlos/shortform/data/AcronymsDataRepository.kt index 30f4b85..4cf7604 100644 --- a/shortform/src/main/java/dev/carlos/shortform/data/AcronymsDataRepository.kt +++ b/shortform/src/main/java/dev/carlos/shortform/data/AcronymsDataRepository.kt @@ -11,6 +11,6 @@ class AcronymsDataRepository( ) : AcronymsRepository { override fun getAcronymDefinition(acronym: String): Single { - return remoteDatasource.getAcronymDefinition(acronym).map { it.single()?.toShortformModel() } + return remoteDatasource.getAcronymDefinition(acronym).map { it.single().toShortformModel() } } } diff --git a/shortform/src/main/java/dev/carlos/shortform/di/AcronymsModule.kt b/shortform/src/main/java/dev/carlos/shortform/di/AcronymsModule.kt index 2324c20..8e6ad5b 100644 --- a/shortform/src/main/java/dev/carlos/shortform/di/AcronymsModule.kt +++ b/shortform/src/main/java/dev/carlos/shortform/di/AcronymsModule.kt @@ -9,6 +9,8 @@ import dev.carlos.shortform.data.cloud.retrofit.AcronymsRemoteDatasource import dev.carlos.shortform.data.cloud.retrofit.AcronymsService import dev.carlos.shortform.domain.AcronymsRepository import dev.carlos.shortform.domain.GetAcronymDefinition +import dev.carlos.shortform.viewmodels.AcronymsViewmodel +import org.koin.androidx.viewmodel.dsl.viewModel import org.koin.dsl.module val acronymsModule = module { @@ -22,4 +24,6 @@ val acronymsModule = module { factory { AcronymsDataRepository(get()) } factory { GetAcronymDefinition(get(), get()) } + + viewModel { AcronymsViewmodel(get()) } } diff --git a/shortform/src/main/java/dev/carlos/shortform/viewmodels/AcronymsViewmodel.kt b/shortform/src/main/java/dev/carlos/shortform/viewmodels/AcronymsViewmodel.kt new file mode 100644 index 0000000..276418b --- /dev/null +++ b/shortform/src/main/java/dev/carlos/shortform/viewmodels/AcronymsViewmodel.kt @@ -0,0 +1,37 @@ +package dev.carlos.shortform.viewmodels + +import androidx.lifecycle.MutableLiveData +import dev.carlos.core.domain.network.RequestError +import dev.carlos.core.domain.network.RequestState +import dev.carlos.core.viewmodel.RxViewModel +import dev.carlos.shortform.data.models.ShortformModel +import dev.carlos.shortform.domain.GetAcronymDefinition +import retrofit2.HttpException +import java.net.UnknownHostException + +class AcronymsViewmodel( + private val GetAcronymsDefinition: GetAcronymDefinition +) : RxViewModel() { + + val acronymDefinition = MutableLiveData() + + fun fetchAcronymDefinition(acronym: String) { + val disposable = GetAcronymsDefinition.getAcronymDefinition(acronym) + .doOnSubscribe { acronymDefinition.postValue(RequestState.Loading) } + .subscribe(::handleSuccess, ::handleError) + compositeDisposable.add(disposable) + } + + private fun handleSuccess(definition: ShortformModel) { + acronymDefinition.postValue(RequestState.Success(definition)) + } + + private fun handleError(exception: Throwable) { + when (exception) { + is NoSuchElementException -> acronymDefinition.postValue(RequestState.Empty) + is UnknownHostException -> acronymDefinition.postValue(RequestState.Error(RequestError.NO_NETWORK)) + is HttpException -> acronymDefinition.postValue(RequestState.Error(RequestError.BAD_RESPONSE)) + else -> acronymDefinition.postValue(RequestState.Error(RequestError.UNKNOWN_PROBLEM)) + } + } +} \ No newline at end of file