0

I am trying to implement searching of places by name in android. I have created two entities, Word and Place.

@Parcelize
@Entity
data class Place(
    @PrimaryKey
    val id: String,
    val name: String,
    val icon: String,
    val latitude: Double,
    val longitude: Double,
    val address: String
) : Parcelable
@Entity
data class Word(
    @PrimaryKey(autoGenerate = true)
    val id: Int = 0,
    val searchWord: String,
    val placeId: String
)

I have also created another data class to model a one-to-many relationship between Word and Place.

data class WordWithPlaces(
    @Embedded
    val word: Word,
    @Relation(parentColumn = "placeId", entityColumn = "id")
    val places: List<Place>
)

The problem I am getting is that when I query the data I get null.

This is the query function in the dao.

  @Transaction
    @Query("SELECT * FROM Word WHERE searchWord = :searchWord")
    fun getWordsWithPlaces(searchWord: String): LiveData<WordWithPlaces>

I need help getting the implementation to work.

Gilbert
  • 2,699
  • 28
  • 29
  • 1
    May be your problem is because of using LiveData, not because of Room? Do you use "observe" with LiveData in your Fragment/Activity? If not - you should, since without observer "getWordsWithPlaces(word).value" will be null – sergiy tikhonov May 21 '20 at 18:00
  • Makes sense. Let me check that. – Gilbert May 21 '20 at 18:03

1 Answers1

0

My mistake was in the architecture.

This was not a one-to-many relationship but a many-to-many relationship. I had to use two queries to implement the search.

    // search for places online based on a searchWord
    // create words consisting of each place's id and the searchWord
    // save the words and places in the database
    suspend fun searchPlaces(searchWord: String) {
        return try {
            val searchResults: PlaceTextSearch = getNetworkService().searchPlaces(searchWord)
            val places = searchResults.places
            val words = places.map { Word(word = searchWord, placeId = it.id) }
            dao.insertWords(words)
            dao.insertPlaces(places)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    // get the words matching a searchword
    // get all related places based on those words
    suspend fun getPlaces(searchWord: String): List<Place> {
        val words = dao.getWords(searchWord)
        val placeIds = words.map { it.placeId }.toTypedArray()
        return dao.getPlaces(placeIds)
    }

Gilbert
  • 2,699
  • 28
  • 29