Reputation: 484
I have made a TypeConverter but I get an error
Unable to create converter for class .models.lastanime.EpisodesEntityfor method EpisodesApi.getEpisodes
I can't finish understanding how to make the TypeConverter, I have done this, I know that the implementation is placed correctly since I have not had problems in the compilation, but the data does not load since I get an error, and it seems that it is not saved in the room database
TYPE CONVERTER
class ListStringConverter {
@TypeConverter
fun fromString(value: String?): List<ServerEntity> {
val listType = object :
TypeToken<List<ServerEntity?>?>() {}.type
return Gson()
.fromJson<List<ServerEntity>>(value, listType)
}
@TypeConverter
fun listToString(list: List<ServerEntity?>?): String {
val gson = Gson()
return gson.toJson(list)
}
}
MODEL EPISODES ENTITY
data class EpisodesEntity(
@SerializedName("episodes")
val episodes: List<EpisodeEntity>
)
MODEL EPISODE ENTITY
@Entity
data class EpisodeEntity(
@PrimaryKey(autoGenerate = true)
val id: Int,
@SerializedName("poster")
@ColumnInfo(name = "episode")
val episode: Int?,
@SerializedName("poster")
@ColumnInfo(name = "poster")
val poster: String?,
@SerializedName("servers")
@ColumnInfo(name = "servers")
val servers: List<ServerEntity>?,
@SerializedName("title")
@ColumnInfo(name = "title")
val title: String?
)
In addition to all the model, the list of Servers is what gives me trouble inserting it in room
@SerializedName("servers")
@ColumnInfo(name = "servers")
val servers: List<ServerEntity>?,
API REPOSITORY
interface LastEpisodesRepository {
fun lastEpisodes(): Flow<Either<Failure, List<Episode>>>
class Network(
private val networkHandler: NetworkHandler,
private val service: LastEpisodesService,
private val local: EpisodeLocal
) : LastEpisodesRepository {
val preferences by lazy { SharedPrefsHelpers() }
override fun lastEpisodes(): Flow<Either<Failure, List<Episode>>> =
flow {
val days = local.getEpisodes()
val time = preferences.getLong(LocalShared.LastAnimes.lastepisodes, 0L)
if (days.isNullOrEmpty() || time == 0L || isFetchCurrentNeeded(time)) {
emit(getRemoteDay())
} else {
emit(Either.Right(local.getEpisodes().map { it.toEpisode() }))
}
}.catch {
emit(Either.Left(Failure.CustomError(ServiceKOs.DATABASE_ACCESS_ERROR, "DB Error")))
}.flowOn(Dispatchers.IO)
private fun getRemoteEpisode(): Either<Failure, List<Episode>> =
when (networkHandler.isConnected) {
true -> request(
service.getEpisodes(),
{ episodeEntity ->
val episodeList: List<EpisodeEntity> = episodeEntity.episodes
preferences.saveLong(LocalShared.LastAnimes.lastepisodes, Date().time)
addAllEpisodes(episodeList)
episodeList.map { it.toEpisode() }
},
EpisodesEntity(emptyList())
)
false, null -> Either.Left(Failure.NetworkConnection())
}
private fun addAllEpisodes(episodes: List<EpisodeEntity>) {
for (episode in episodes) {
local.addEpisodes(episode)
}
}
}
Room are the calls that are made from the local variable, the application checks if there is downloaded data and if there is not, it calls the service, returns the data and at the same time saves it in the Room database.
Upvotes: 1
Views: 4466
Reputation: 484
After several days carefully studying more about the advanced inserts of Room, I have discovered how to make the TypeConverter for a specific custom object, In my case ServersEntity
@TypeConverter
fun stringToListServer(data: String?): List<ServerEntity?>? {
if (data == null) {
return Collections.emptyList()
}
val listType: Type = object :
TypeToken<List<ServerEntity?>?>() {}.type
return gson.fromJson<List<ServerEntity?>>(data, listType)
}
@TypeConverter
fun listServerToString(someObjects: List<ServerEntity?>?): String? {
return gson.toJson(someObjects)
}
On the other hand to convert the String lists, it would simply be done as follows
@TypeConverter
fun fromString(value: String?): List<String> {
val listType = object :
TypeToken<ArrayList<String?>?>() {}.type
return Gson().fromJson(value, listType)
}
@TypeConverter
fun fromList(list: List<String?>?): String {
val gson = Gson()
return gson.toJson(list)
}
Upvotes: 4
Reputation: 1006869
You cannot have an entity holding a List
of another entity. You need to define a one-to-many relation between them.
Upvotes: 1