Skip to content

Data models and TypeConverter

Nikita Kalugin edited this page Apr 18, 2021 · 2 revisions

This app is working with the server API from KODE. This API has two endpoint (as far as I know).

  1. https://test.kode-t.ru/recipes
  2. https://test.kode-t.ru/recipes/{recipe-uuid}

First one returns a list of recipes. App parse them into list - List<Recipe>. Here's how Recipe class looks like. Also, as you can notice, this class is an entity for Room database.

@Parcelize
@Entity(tableName = "recipe")
data class Recipe(
        @PrimaryKey val uuid: String,
        val name: String,
        val images: List<String>,
        val lastUpdated: Long,
        val description: String?,
        val instructions: String?,
        val difficulty: Int
) : Parcelable

Here comes the important question. How do I store a list of strings (list of images) in a column? Simply by using TypeConverter.

class Converters {
    @TypeConverter
    fun fromString(stringListString: String): List<String> {
        return stringListString.split("<&>").map { it }
    }

    @TypeConverter
    fun toString(stringList: List<String>): String {
        return stringList.joinToString(separator = "<&>")
    }

This converter join every string into one string separated with <&> symbol. And when we need to get this strings back it splits this string into list of strings.


Second API endpoint returns just one Recipe object, but now it has a list of RecipeBrief object as well, its some kind of recipe recommendations for the actual recipe user clicked at. So I've created another two classes for this endpoint.

@Parcelize
@Entity(tableName = "recipeDetails")
data class RecipeDetails(
        @PrimaryKey val uuid: String,
        val name: String,
        val images: List<String>,
        val lastUpdated: Long,
        val description: String?,
        val instructions: String?,
        val difficulty: Int,
        val similar: List<RecipeBrief>
) : Parcelable

@Parcelize
data class RecipeBrief(
        val uuid: String,
        val name: String,
        val image: String
) : Parcelable

Only RecipeDetails class is stored into database directly as a table. RecipeBrief is just a column named similar in the RecipeDetails table.

But how can I store object as a column? Its simply as before with TypeConverter.

    @TypeConverter
    fun fromRecipeBriefList(value: List<RecipeBrief>): String {
        val type = object : TypeToken<List<RecipeBrief>>() {}.type
        return Gson().toJson(value, type)
    }

    @TypeConverter
    fun toRecipeBriefList(value: String): List<RecipeBrief> {
        val type = object : TypeToken<List<RecipeBrief>>() {}.type
        return Gson().fromJson(value, type)
    }
Clone this wiki locally