0

I have some view model:

    private val locationFlow = locationProviderClient.locationFlow(LocationModule.locationRequest)

    val position = MutableStateFlow(Location(LocationManager.NETWORK_PROVIDER))
    val positions = MutableStateFlow(emptyList<Position>())

    init {
        collectLocation()
    }

    private fun collectLocation() {
        viewModelScope.launch {
            locationFlow.collect {
                position.value = it
                positions.value = positionService.updateLocation(it.toPosition())
            }
        }
    }

On initialization flow of current location is starting. On each new value last position should be emitted into position state flow and network request should be performed. Here's fragment code responsible for collecting state flows

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        lifecycleScope.launchWhenStarted {
                ...
                viewModel.positions.collect(updateMarkers)
                viewModel.position.collect(updateCamera)
                ...
            }
}

Now, when fragment starts location is emitted, both flows are updated, request is send updateMarkers is called but updateCamera is not.

I suppose there is some subtle bug, if no can anybody tell me what the hell I'm doing wrong?

General Grievance
  • 4,555
  • 31
  • 31
  • 45
Karol Kulbaka
  • 1,136
  • 11
  • 21
  • Where is updateCamera function? – charlie.7 Sep 29 '21 at 09:52
  • `collect` is a suspend function, you should call it in different coroutines (launch) – IR42 Sep 29 '21 at 09:54
  • @charlie.7 ```private val GoogleMap.updateCamera: suspend (Location) -> Unit get() = { animateCamera(CameraUpdateFactory.newLatLngZoom(it.toLatLng(), ZOOM_STREETS)) }``` it is working like it should but - but not called – Karol Kulbaka Sep 29 '21 at 09:57

2 Answers2

2

The collects of your two flows are not concurrent, they are still executed sequentially.


override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        lifecycleScope.launch(Dispatchers.IO) {
                ...
                viewModel.positions.collect(updateMarkers)
                ...
            }

        lifecycleScope.launch(Dispatchers.IO) {
                ...
                viewModel.position.collect(updateCamera)
                ...
            }
    }

Future Deep Gone
  • 831
  • 6
  • 16
0
override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        lifecycleScope.launchWhenStarted {
                ...
                launch {
                   viewModel.positions.collect(updateMarkers)
                }
                launch {
                   viewModel.position.collect(updateCamera)
                }
                ...
            }
    }
charlie.7
  • 329
  • 3
  • 5