Insert retrofit response in Room Kotlin

Viewed 1849

I am trying to insert response.body() in a arraylist but it's getting null. The idea is to send the data from server to a database. I can show it in the recyclerview without any problem, but no idea how to store all the data locally.

Here the code:

    val service = client!!.create(ApiInterface::class.java)
    val call = service.pOIs
    call!!.enqueue(object : Callback<PoiResponse?> {
        override fun onResponse(call: Call<PoiResponse?>, response: Response<PoiResponse?>) {
            if (response.isSuccessful) {
                
                val result = response.body()
                //here i send the response to a poi model to show it in a recyclerview, works fine
                val poiList: ArrayList<Poi>? = result?.list
                
                //same data, but for persistence
                val poiRoomList: ArrayList<PoiRoom>? = result?.roomList //here is getting null

                onFinishedListener!!.onFinished(poiList, poiRoomList)

Response:

class PoiResponse {
    var list: ArrayList<Poi>? = null
    var roomList: ArrayList<PoiRoom>? = null
}

Dao:

@Dao
interface PoiDao {

   @Insert(onConflict = OnConflictStrategy.IGNORE)
   fun insert(poiRoom: PoiRoom)

   @Insert(onConflict = REPLACE)
   fun insertAllPois(poisRoomList: List<PoiRoom>?);


   @Query("SELECT * FROM poi_table")
   fun getAllPois(): LiveData<List<PoiRoom>>
   
}

Entity:

@Entity(tableName = "poi_table")
class PoiRoom(
        @PrimaryKey(autoGenerate = true)
        var id: Int = 0,
        @ColumnInfo(name = "title")
        val title: String,
        @ColumnInfo(name = "address")
        val address: String,
        @ColumnInfo(name = "transport")
        val transport: String,
        @ColumnInfo(name = "email")
        val email: String,
        @ColumnInfo(name = "geocoordinates")
        val geocoordinates: String,
        @ColumnInfo(name = "description")
        val description: String)
       

Json response, a list of points of interest:

{
  "list": [
    {
      "id": "1",
      "title": "Casa Batlló",
      "geocoordinates": "41.391926,2.165208"
    },
    {
      "id": "2",
      "title": "Fundació Antoni Tàpies",
      "geocoordinates": "41.39154,2.163835"
    },

Database class:

@Database(entities = [PoiRoom::class], version = 1)
abstract class PoiRoomDatabase : RoomDatabase() {

    abstract fun poiDao(): PoiDao

    companion object {
        @Volatile
        private var INSTANCE: PoiRoomDatabase? = null

        fun getDatabase(
                context: Context,
                scope: CoroutineScope
        ): PoiRoomDatabase {
            return INSTANCE ?: synchronized(this) {
                val instance = Room.databaseBuilder(
                        context.applicationContext,
                        PoiRoomDatabase::class.java,
                        "poi_database"
                )
                        .fallbackToDestructiveMigration()
                        .build()
                INSTANCE = instance
                instance
            }
        }

    }
}

SOLUTION:

1º) Elimination of arraylist from response

2º) Mapped Roomlist with poilist like this:

  val mappedRoomList =   poiList?.map { PoiRoom(it.id, it.title, it.address, it.transport, it.email, it.geocoordinates, it.description) }

3º) Created method to add mappedlist to roomdatabase:

override fun sendDataToRoomDataBase(poiOfflineList: List<PoiRoom?>?) {

     poiDao?.insertAllPois(poiOfflineList)

    }

4º)Created Converter:

class PoiConverters {
  
        private val gson = Gson()

        @TypeConverter
        fun stringToListPoi(data: String?): List<Poi?>? {
            if (data == null) {
                return Collections.emptyList()
            }
            val listType: Type = object :
                    TypeToken<List<Poi?>?>() {}.type

            return gson.fromJson<List<Poi?>>(data, listType)
        }

        @TypeConverter
        fun listPoiToString(list: List<Poi?>?): String? {
            return gson.toJson(list)
        }
}

And thats all :)

1 Answers

Well, as far I can see, check your Json response: There you only have "list" key, and not "roomList" key. It means, that when you parse response Json and insert into ArrayList, you only "fill" up list type objects, not roomList, because it does not exist! What I would do is map your response List and map it to your RoomList objects using map function. Try something like this:

override suspend fun insertAllPoiIntoDb(poiList: List<Poi>) {
   yourDatabase.yourDao().insertAllObjectsFunction(
     poiList.map {
       it.toRoomObject()
     }
  )
}

toRoomObject() function represent some function logic in your Poi object, which converts Poi into RoomPoi(that is construction of object).

Related