0

Why it's not possible to directly set the mutableLiveData.value when using a suspend function? See following code:

private val _clubs: MutableLiveData<List<ClubEntity>> by lazy {
    MutableLiveData<List<ClubEntity>>().also {
        fetchClubListFromRepository()
    }
}

private fun fetchClubListFromRepository() {
        viewModelScope.launch {
            // This does NOT work, no error but the UI does not update.
            // _clubs.value = clubsRepository.getAllClubs()
            // This works, the UI updates.
            var clubsList = clubsRepository.getAllClubs()
            _clubs.value = clubsList
        }
}

suspend fun getAllClubs(): List<ClubEntity> = withContext(Dispatchers.IO) {
        ClubsApi.RETROFIT_SERVICE.getClubs()
    }

Github repo

David
  • 3,971
  • 1
  • 26
  • 65
  • At first glance both look fine and exactly equivalent. By "does not work", what do you mean happens? Compile error or nothing happens at runtime, or...? – Tenfour04 Jul 11 '22 at 13:34
  • With "does not work" I mean that the UI does not change, it changes with the second approach, no error whatsoever. – David Jul 11 '22 at 13:37
  • Initially it's null that's why liveData not updated clubsRepository.getAllClubs()?.let{ _clubs.value =it } – Gobu CSG Jul 11 '22 at 13:42
  • @GobuCSG it's not null. – David Jul 11 '22 at 13:46
  • may be It's asynchronous call – Gobu CSG Jul 11 '22 at 13:47
  • Have you tried to remove `.also` and just `private val _clubs: MutableLiveData> by lazy { fetchClubListFromRepository() }` ? After modifying method of course. – SkypeDogg Jul 11 '22 at 14:45
  • @SkypeDogg have you tried it? That wouldn't compile. – David Jul 11 '22 at 15:41
  • I think the root problem is this `suspend fun getClubs(): List` it should be `suspend fun getClubs(): Response>` – cutiko Jul 11 '22 at 15:53
  • @cutiko That's not the root problem, it may be the solution though. I think the problem is a timing issue, when fetchClubListFromRepository is called it seems that _clubs is still not initialized so fetchClubListFromRepository() is actually called again. With the 2nd approach background work is running which gives the runtime time to complete the initialization, at least that's how I understand it currently. – David Jul 12 '22 at 02:17

1 Answers1

0

I think the problem is a timing issue, when fetchClubListFromRepository is called it seems that _clubs is still not initialized so fetchClubListFromRepository() is actually called again. With the 2nd approach background work is running which gives the runtime time to complete the initialization, at least that's how I understand it currently.

David
  • 3,971
  • 1
  • 26
  • 65