-
Notifications
You must be signed in to change notification settings - Fork 0
Application ShoppingApp
Devrath edited this page Jul 11, 2021
·
21 revisions
Contents-and-observations |
|---|
| Wrapping the live data in the Util Event class |
| Declaring live data observable in view model |
| Creating a Fake repository |
- When we are creating an observable source like
live dataorflowwe need to give the ability to modify the live data by the components inside the ViewModel. Then expose a variable for outside so it can be observed. - Thus mutable state is for the view model since only the view model should modify it, thus it's private.
- We just expose the Live data since it just can be observed and not be modified and has no mutable state, thus it's public.
Declare in viewmodel
private val _images = MutableLiveData<Event<Resource<ImageResponse>>>()
val images: LiveData<Event<Resource<ImageResponse>>> = _imagesSet the data in viewmodel
images.value = // set the stateObserve the live data from outside the view model, like activity or fragment
viewModel.images.observe(viewLifecycleOwner, Observer {- We create a fake repository when we can
swapbetween areal repositoryand afake repositorydepending on our usage. - We use a
real repositorywhen we are running our production code. - We use a
fake repositorywhen we are testing our test cases. - We inject the interface of the
repositoryin theview modelconstructor. - Now we need to create classes of the repositories (
real repository,fake repository) that implements the interface which we inject into theview model. - We. create the instance of the class that implements the interface using the hilt provides a method using a dagger
ShoppingRepository.kt -> This is useful in swapping the implementation for both the production and test cases of repository implementation
interface ShoppingRepository {
suspend fun insertShoppingItem(shoppingItem: ShoppingItem)
suspend fun deleteShoppingItem(shoppingItem: ShoppingItem)
fun observeAllShoppingItems(): LiveData<List<ShoppingItem>>
fun observeTotalPrice(): LiveData<Float>
suspend fun searchForImage(imageQuery: String): Resource<ImageResponse>
}DefaultShoppingRepository.kt -> This can be used in production code
class DefaultShoppingRepository @Inject constructor(
private val shoppingDao: ShoppingDao,
private val pixabayAPI: PixabayAPI
) : ShoppingRepository {
override suspend fun insertShoppingItem(shoppingItem: ShoppingItem) {}
override suspend fun deleteShoppingItem(shoppingItem: ShoppingItem) {}
override fun observeAllShoppingItems(): LiveData<List<ShoppingItem>> {}
override fun observeTotalPrice(): LiveData<Float> {}
override suspend fun searchForImage(imageQuery: String): Resource<ImageResponse> {}
}FakeShoppingRepository.kt -> This can be used in testing unit tests
class FakeShoppingRepository @Inject constructor(
private val shoppingDao: ShoppingDao,
private val pixabayAPI: PixabayAPI
) : ShoppingRepository {
override suspend fun insertShoppingItem(shoppingItem: ShoppingItem) {}
override suspend fun deleteShoppingItem(shoppingItem: ShoppingItem) {}
override fun observeAllShoppingItems(): LiveData<List<ShoppingItem>> {}
override fun observeTotalPrice(): LiveData<Float> {}
override suspend fun searchForImage(imageQuery: String): Resource<ImageResponse> {}
}AppModule.kt -> Here we will cast the interface to the repository making it return the repository, by doing so we can inject the interface and use the overridden methods used in repository
@Module
@InstallIn(ApplicationComponent::class)
object AppModule {
@Singleton
@Provides
fun provideDefaultShoppingRepository(
dao: ShoppingDao,
api: PixabayAPI
) = DefaultShoppingRepository(dao, api) as ShoppingRepository
}