How to perform a room transaction usin Rxjava - android

How can I do a room transaction across 2 different DAOs usin rxjava?
I have this code that I would like to use with Rxjava but I need it to return some kind of observable
#Transaction
fun insertStoreWithPictures(store: Store, pictures: List<StorePicture>) {
insertStore(store)
insertPictures(pictures)
}
The store DAO
#Dao
abstract public class store {
#Insert
Single<Long> insert(store entity);
}
The storePicture DAO
#Dao
abstract public class storePicture {
#Insert
Completable insert(storePicture... entity);
}

I think you can use zip or combine operator of RxJava. It would create an observable from an iterators observable source.

Best example you can follow to achieve the same - https://blog.mindorks.com/understanding-rxjava-zip-operator-with-example

Related

How to convert LiveData Entitiy to LiveData Domain model

I'm developing MVVM kotlin application with repository pattern
I have separated my model classes as below
classes represents the data coming from network
classes represents entities for the room database
classes that represents the domain
In my repository I want always to return the domain object not the network object or the entity object.
In my Dao I insert and retrieve entity object as below
#Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertAsteroids(asteroid: List<AsteroidEntity>)
#Query("SELECT * FROM asteroid_tbl")
fun getAsteroidsFromDb () : LiveData<List<AsteroidEntity>>
And I have a function in the repository that returns the list of asteroids as Live data from room as below
override suspend fun getAsteroids(): LiveData<List<Asteroid>> {
return appLocalDb.asteroidDao.getAsteroidsFromDb()
}
But the issue is the dao returns a LiveData<List<AsteroidEntity>>
while the repository I want it to return the domain model as
LiveData<List<Asteroid>>
Any suggestion on how to solve this problem?
Use Transformations.map
override suspend fun getAsteroids(): LiveData<List<Asteroid>> {
return Transformations.map(appLocalDb.asteroidDao.getAsteroidsFromDb()) { it.map{ item -> Asteroid(item.name,....)} }
}
For Further Documentation checkout the docs
https://developer.android.com/reference/android/arch/lifecycle/Transformations

Room returning blank object

I'm posting my room query result using the below code
_data.postValue(databaseImpl.findRepoById(id).value)
But it seems the returned object is empty. I'm guessing we need to observe databaseImpl.findRepoById(id), not access it directly but since it's in a viewmodel I don't have a lifecycleOwner to assign to the room query livedata.
databaseImpl.observe(this, Observer { //!!this is modelview and not activity
_data.postValue()
})
What is the right way to use Room query and update a mediator live data?
You could try use coroutines to query your data so you can have something like this for your DAO:
#Query("SELECT * FROM users")
fun findRepoById(id): Flow<User>
In your DatabaseImpl class return have it as:
fun findRepoById(id): Flow<User> = userDao.findRepoById(id)
Then in your ViewModel you could do this:
viewModelScope.launch {
databaseImpl.findRepoById(id).map { _data.postValue(it) }
}
Have a look at this article Room and Coroutines by Florina Muntenescu
on how you could set up coroutines and use it with room.

How to return id after saving a record room using RxJava + MVVM

I'm developing an android app with Kotlin.
I'm using RxJava and MVVM.
i tried this :
a link
Here is one of my method in DataSource interface
fun insertPhoneNumber(phoneNumber: PhoneNumber) : Long
fun insertAllPhoneNumber(phoneNumberList: List<PhoneNumber>): List<Long>
The question is, after building the basic classes and requirements.
The compiler issues an error as follows:
e: [kapt] An exception occurred: java.lang.IllegalArgumentException:
long cannot be converted to an Element
I want to return the corresponding ID when a record is stored in my table
If you're using RxJava your Dao interface should look like this...
#Dao
interface WhateverDao {
#Insert
fun insertPhoneNumber(phoneNumber: PhoneNumber) : Maybe<Long>
#Insert
fun insertAllPhoneNumber(vararg phoneNumberList: PhoneNumber): Maybe<List<Long>>
}
Changes are:
Mark the interface with #Dao
Mark insert methods with #Insert
Pass a vararg to the insert all method
Use RxJava classes on the return type to make use of the reactive-streams pattern

How to write a Room Database Adapter to wrap result type

What i want to achieve is to wrap a specific type for room database query result
The same as we doing now with android.arch.persistence.room:rxjava2 library that helps to expose RxJava2 Types like Observables and Flowables in the result
example :
abstract Single<User> find(String id);
Is there any specific Adapter or a way that can help to acheive this wrapping ? or create and artifact same as android.arch.persistence.room:rxjava2
for Coroutines as an example
Add implementation "android.arch.persistence.room:rxjava2:1.1.0" to you build.gradle.
https://developer.android.com/training/data-storage/room/accessing-data#query-rxjava
#Dao
public interface MyDao {
#Query("SELECT * from user where id = :id LIMIT 1")
public Flowable<User> loadUserById(int id);
}

merging result of one observable to another

I have a situation which I haven't been able to solve via RxJava2 operators.
I have a list of "Matches" I retrieve from Room. Here is my Match POJO.
public class Match {
#PrimaryKey
private int id;
#Ignore
Team rivalTeam;
}
Here is my Dao for this table.
#Dao
public interface MatchDao {
#Query("select * from `match` where homeTeamId= :homeTeamId")
Single<List<Match>> getMatchesByTeamId(int homeTeamId);
}
My target is to create an observable which will pull out these matches and then merge it with an observable which would be returning the rivalTeam.
Here is my Team Dao
#Dao
public interface TeamDao {
#Query("select * from teams where id = :teamId")
Single<Team> getTeamById(int teamId);
}
What I have achieved is this.
private Single<List<Match>> fetchMatches(Team team) {
return matchDao.
getMatchesByTeamId(team.getId()).toObservable().
flatMapIterable(matches -> matches).
map(match -> teamDao.getTeamById(**match.getRivalId()**).toObservable() // this doesn't work ofcourse since map can't return an observable.);
}
I know I have to perhaps zip both observables , but how would I go about doing that since the second observable is dependent on the first?.
If zip would have worked on a single source , I would have been able to do a
match.setRivalTeam(team) in the zipper method.
Hints?

Categories

Resources