https://kotlinlang.org logo
Join the conversationJoin Slack
Channels
100daysofcode
100daysofkotlin
100daysofkotlin-2021
advent-of-code
aem
ai
alexa
algeria
algolialibraries
amsterdam
android
android-architecture
android-databinding
android-studio
androidgithubprojects
androidthings
androidx
androidx-xprocessing
anime
anko
announcements
apollo-kotlin
appintro
arabic
argentina
arkenv
arksemdevteam
armenia
arrow
arrow-contributors
arrow-meta
ass
atlanta
atm17
atrium
austin
australia
austria
awesome-kotlin
ballast
bangladesh
barcelona
bayarea
bazel
beepiz-libraries
belgium
berlin
big-data
books
boston
brazil
brikk
budapest
build
build-tools
bulgaria
bydgoszcz
cambodia
canada
carrat
carrat-dev
carrat-feed
chicago
chile
china
chucker
cincinnati-user-group
cli
clikt
cloudfoundry
cn
cobalt
code-coverage
codeforces
codemash-precompiler
codereview
codingame
codingconventions
coimbatore
collaborations
colombia
colorado
communities
competitive-programming
competitivecoding
compiler
compose
compose-android
compose-desktop
compose-hiring
compose-ios
compose-mp
compose-ui-showcase
compose-wear
compose-web
connect-audit-events
corda
cork
coroutines
couchbase
coursera
croatia
cryptography
cscenter-course-2016
cucumber-bdd
cyprus
czech
dagger
data2viz
databinding
datascience
dckotlin
debugging
decompose
decouple
denmark
deprecated
detekt
detekt-hint
dev-core
dfw
docs-revamped
dokka
domain-driven-design
doodle
dsl
dublin
dutch
eap
eclipse
ecuador
edinburgh
education
effective-kotlin
effectivekotlin
emacs
embedded-kotlin
estatik
event21-community-content
events
exposed
failgood
fb-internal-demo
feed
firebase
flow
fluid-libraries
forkhandles
forum
fosdem
fp-in-kotlin
framework-elide
freenode
french
fritz2
fuchsia
functional
funktionale
gamedev
ge-kotlin
general-advice
georgia
geospatial
german-lang
getting-started
github-workflows-kt
glance
godot-kotlin
google-io
gradle
graphic
graphkool
graphql
graphql-kotlin
graviton-browser
greece
grpc
gsoc
gui
hackathons
hacktoberfest
hamburg
hamkrest
helios
helsinki
hexagon
hibernate
hikari-cp
hire-me
hiring
hongkong
hoplite
http4k
hungary
hyderabad
image-processing
india
indonesia
inkremental
intellij
intellij-plugins
intellij-tricks
internships
introduce-yourself
io
ios
iran
israel
istanbulcoders
italian
jackson-kotlin
jadx
japanese
jasync-sql
java-to-kotlin-refactoring
javadevelopers
javafx
javalin
javascript
jdbi
jhipster-kotlin
jobsworldwide
jpa
jshdq
juul-libraries
jvm-ir-backend-feedback
jxadapter
k2-early-adopters
kaal
kafka
kakao
kalasim
kapt
karachi
karg
karlsruhe
kash_shell
kaskade
kbuild
kdbc
kgen-doc-tools
kgraphql
kinta
klaxon
klock
kloudformation
kmdc
kmm-español
kmongo
knbt
knote
koalaql
koans
kobalt
kobweb
kodein
kodex
kohesive
koin
koin-dev
komapper
kondor-json
kong
kontent
kontributors
korau
korean
korge
korim
korio
korlibs
korte
kotest
kotest-contributors
kotless
kotlick
kotlin-asia
kotlin-beam
kotlin-by-example
kotlin-csv
kotlin-data-storage
kotlin-foundation
kotlin-fuel
kotlin-in-action
kotlin-inject
kotlin-latam
kotlin-logging
kotlin-multiplatform-contest
kotlin-mumbai
kotlin-native
kotlin-pakistan
kotlin-plugin
kotlin-pune
kotlin-roadmap
kotlin-samples
kotlin-sap
kotlin-serbia
kotlin-spark
kotlin-szeged
kotlin-website
kotlinacademy
kotlinbot
kotlinconf
kotlindl
kotlinforbeginners
kotlingforbeginners
kotlinlondon
kotlinmad
kotlinprogrammers
kotlinsu
kotlintest
kotlintest-devs
kotlintlv
kotlinultimatechallenge
kotlinx-datetime
kotlinx-files
kotlinx-html
kotrix
kotson
kovenant
kprompt
kraph
krawler
kroto-plus
ksp
ktcc
ktfmt
ktlint
ktor
ktp
kubed
kug-leads
kug-torino
kvision
kweb
lambdaworld_cadiz
lanark
language-evolution
language-proposals
latvia
leakcanary
leedskotlinusergroup
lets-have-fun
libgdx
libkgd
library-development
linkeddata
lithuania
london
losangeles
lottie
love
lychee
macedonia
machinelearningbawas
madrid
malaysia
mathematics
meetkotlin
memes
meta
metro-detroit
mexico
miami
micronaut
minnesota
minutest
mirror
mockk
moko
moldova
monsterpuzzle
montreal
moonbean
morocco
motionlayout
mpapt
mu
multiplatform
mumbai
munich
mvikotlin
mvrx
myndocs-oauth2-server
naming
navigation-architecture-component
nepal
new-mexico
new-zealand
newname
nigeria
nodejs
norway
npm-publish
nyc
oceania
ohio-kotlin-users
oldenburg
oolong
opensource
orbit-mvi
osgi
otpisani
package-search
pakistan
panamá
pattern-matching
pbandk
pdx
peru
philippines
phoenix
pinoy
pocketgitclient
polish
popkorn
portugal
practical-functional-programming
proguard
prozis-android-backup
pyhsikal
python
python-contributors
quasar
random
re
react
reaktive
realm
realworldkotlin
reductor
reduks
redux
redux-kotlin
refactoring-to-kotlin
reflect
refreshversions
reports
result
rethink
revolver
rhein-main
rocksdb
romania
room
rpi-pico
rsocket
russian
russian_feed
russian-kotlinasfirst
rx
rxjava
san-diego
science
scotland
scrcast
scrimage
script
scripting
seattle
serialization
server
sg-user-group
singapore
skia-wasm-interop-temp
skrape-it
slovak
snake
sofl-user-group
southafrica
spacemacs
spain
spanish
speaking
spek
spin
splitties
spotify-mobius
spring
spring-security
squarelibraries
stackoverflow
stacks
stayhungrystayfoolish
stdlib
stlouis
strife-discord-lib
strikt
students
stuttgart
sudan
swagger-gradle-codegen
swarm
sweden
swing
swiss-user-group
switzerland
talking-kotlin
tallinn
tampa
teamcity
tegal
tempe
tensorflow
terminal
test
testing
testtestest
texas
tgbotapi
thailand
tornadofx
touchlab-tools
training
tricity-kotlin-user-group
trójmiasto
truth
tunisia
turkey
turkiye
twitter-feed
uae
udacityindia
uk
ukrainian
uniflow
unkonf
uruguay
utah
uuid
vancouver
vankotlin
vertx
videos
vienna
vietnam
vim
vkug
vuejs
web-mpp
webassembly
webrtc
wimix_sentry
wwdc
zircon
Powered by Linen
flow
  • a

    Andrea

    02/23/2022, 11:43 PM
    Hi everyone, I have a doubt regarding the flatMapLatest and the UDF. I have pasted a simplified code version with more details. I would like to create a UIState in my viewmodel, with several properties (example like HomeUiState in JetNews). One of these properties is a list of users that might be filtered by the user. 1 - The first approach would be exposing the list, which would be filtered every time the userId changes. In this case I would not be able to add the list into my UIState. 2 - The second one would be collecting the flow into the init and update the UIState in the onEach. In this case though, I would need to trigger the userId from the UI in order to start it the first time. Any suggestions for situations like this? Am I doing anything wrong? Thanks!
    data class HomeUiState(
        val users: MutableList<User>
    )
    
    class HomeViewModel(
    ) : ViewModel(){
    
        private val repository: Repository = Repository()
    
        private val viewModelState = MutableStateFlow(HomeUiState(mutableListOf()))
        val uiState: StateFlow<HomeUiState> = viewModelState
            .stateIn(
                viewModelScope,
                SharingStarted.Eagerly,
                viewModelState.value
            )
    
        val userId = MutableStateFlow(1)
    
        //  1 solutions: Keep the list out the UIState and collect it in compose with collectAsState 
        val userList = userId.flatMapLatest {
            repository.getUsersList()
        }.stateIn(
            viewModelScope,
            SharingStarted.WhileSubscribed(5000),
            emptySet()
        )
    
        // 2 solution, flatMapLatest for the filtered list
        init {
            userId.flatMapLatest {
                repository.getUsersList(it)
            }.onEach { users ->
                viewModelState.update {
                    it.copy(users = users) }
            }.launchIn(viewModelScope)
        }
    }
    n
    • 2
    • 5
  • e

    expensivebelly

    03/01/2022, 7:14 PM
    Any guide on how to migrate
    @ObsoleteCoroutinesApi
    public fun <E> CoroutineScope.broadcast(
        context: CoroutineContext = EmptyCoroutineContext,
        capacity: Int = 1,
        start: CoroutineStart = CoroutineStart.LAZY,
        onCompletion: CompletionHandler? = null,
        @BuilderInference block: suspend ProducerScope<E>.() -> Unit
    ): BroadcastChannel<E>
    to
    SharedFlow
    ?
    n
    • 2
    • 3
  • m

    Michael Marshall

    03/03/2022, 4:12 AM
    Is there a function that splits a
    Flow<UnmappedValue>
    into a
    Map<SomeKey, Flow<MappedValue>>
    ? Like the opposite of
    merge
    ? Maybe
    explode
    or
    subFlows
    or something like that?
    w
    • 2
    • 2
  • c

    Colton Idle

    03/08/2022, 12:43 AM
    Still not super comfortable with flows, but Im getting a laggy UI in my android app with the following, and was wondering if anyone had any pointers. Basically I just have a search field and as a user types, I want to search against my api, but I want to make sure to wait 250ms before hitting a network call.
    var queryText = MutableStateFlow("")
    init {
      viewModelScope.launch {
        myState.queryText.debounce(250).collect {
            search(it)
        }
      }
    }
    
    private fun search(term: String) {
      viewModelScope.launch {
        val result = service.searchApiCall(term)
    ...
    Now that I think about it. I probably want my old network calls to be cancelled too. Can anyone point me in the right direction about how I should rethink this?
    k
    g
    • 3
    • 11
  • m

    miqbaldc

    03/15/2022, 5:02 AM
    Does it Flow extensions
    single
    is equivalent to
    first
    ? There’s seems a weird issue in my part. When using
    single
    it returns
    null
    , but exist otherwise with
    first
    n
    e
    • 3
    • 5
  • n

    Nicolai

    03/17/2022, 10:54 AM
    Hi, I'm pretty new to using Flows in Kotlin so I'm having an issue I hope one of you can provide me some help to. I'm trying to chain some requests and if they fail I want them to stop the chaining and just emit an error. Preferably it would be one size fits all so I don't have to check for the Error for each response. Right now I just emit emptyFlow as the IDE will complain if I return nothing Any idea what I can do? (also any other inputs are more than welcome)
    signupUseCase.signUp(createPostRegister(email, password))
         .flatMapConcat {
             when (it) {
                 is NetworkResult.Success -> loginUseCase.login(
                     createPostToken(
                         email,
                         password
                     )
                 )
                 is NetworkResult.Error -> {
                     it.rbError?.let { error -> handleErrors(error) }
                     emptyFlow()
                 }
                 else -> emptyFlow()
             }
         }
         .flatMapConcat {
             when (it) {
                 is NetworkResult.Success -> {
                     prefManager.saveString(AppConstants.TOKEN_STORAGE, it.data)
                     prefManager.saveString(AppConstants.EMAIL_STORAGE, email)
                     prefManager.savePasswordEncrypted(password)
                     updateCountryUseCase.updateCountry()
                     return@flatMapConcat patchSelfUseCase.patchSelf(name, ApiConstants.fullName)
                 }
                 else -> emptyFlow()
             }
         }.flatMapConcat {
             when (it) {
                 is NetworkResult.Success -> getSelfUseCase.getSelf()
                 is NetworkResult.Error -> {
                     it.rbError?.let { error -> handleErrors(error) }
                     emptyFlow()
                 }
                 else -> emptyFlow()
             }
         }.flatMapConcat {
             when (it) {
                 is NetworkResult.Success -> {
                     it.data?.let { self -> instance.setSelf(self) }
                     legalRevisions.value?.let { revisions ->
                         return@flatMapConcat putLegalAcceptUseCase.putLegalAccept(revisions)
                     } ?: run {
                         return@flatMapConcat emptyFlow()
                     }
                 }
                 is NetworkResult.Error -> {
                     it.rbError?.let { error -> handleErrors(error) }
                     emptyFlow()
                 }
                 else -> emptyFlow()
             }
         }.collect { signupCompleted.postValue(true) }
    m
    • 2
    • 4
  • m

    Matthew Laser

    03/24/2022, 5:48 PM
    can anyone provide insight into what the best way to combine two flows is? I’m currentlly using the actual
    combine
    operator, but it’s not getting me quite the result I’m after. Here’s an example of what I’ve got now
    flowOne()
    .combine(flowTwo, { a, b -> Pair(a,b) })
    .onEach { ... }
    While the actual values of the
    Pair
    i’m creating are correct, as far as I can tell, the values are only updated when
    flowOne
    emits a value, only then combining with the latest value from
    flowTwo
    . Is there an elegant operator (or approach) I can use to propagate my
    Pair
    immediately when either
    flowOne
    or
    flowTwo
    update, not just
    flowOne
    ? update: turns out I
    combine
    is what I want! except, rather than
    flowOne.combine(flowTwo)
    , I need
    combine(flowOne, flowTwo)
    :)
    m
    • 2
    • 3
  • a

    Alexander Maryanovsky

    03/24/2022, 6:22 PM
    Is there a way to explicitly create a child coroutine scope? My use case is that I want to create a bunch of `SharedFlow`s and occasionally close them all. The way I’m trying to do that is by creating them with
    shareIn(scope.newChildScope())
    and closing with
    scope.coroutineContext.cancelChildren()
    d
    • 2
    • 4
  • r

    Ryosuke Yamada

    03/28/2022, 4:13 PM
    Hi, I'm new to use Flow so I confused when to use regular
    Flow
    or
    StateFlow
    . Many codes expose
    Flow
    in repository, and convert to
    StateFlow
    in ViewModels like this.
    val userState: StateFlow<User?> = userRepository.userFlow.stateIn(viewModelScope, Eagerly, null)
    This case always show null state on UI started, even if repository has initial value. This problem may be solved by exposing
    StateFlow
    instead of regular
    Flow
    in repository, is it bad practice?
    n
    g
    • 3
    • 9
  • a

    Arun Joseph

    03/28/2022, 6:56 PM
    Hi, I want callbackflow to be shared between subscribers. I see solutions using shareIn for example - https://barbeau.medium.com/kotlin-callbackflow-a-lightweight-architecture-for-location-aware-android-apps-f97b5e66aaa2. But I would like to avoid an external coroutinescope for shareIn. Is there any solutions which relies on a combination of scopes of the subscribers?
    n
    • 2
    • 2
  • a

    Alexander Maryanovsky

    03/29/2022, 8:06 AM
    According to the docs, when the upstream of a SharedFlow completes, the downstream just remains stuck collecting forever. What do you guys think of this utility to work around this? Code in thread.
    • 1
    • 2
  • r

    rcd27

    04/02/2022, 3:12 PM
    Greetings, seems like I misunderstand
    shareIn
    functionality. Trying to share the flow emitions betwenn 3 subscribers, but only one of them (first) is collecting data:
    @Test
      fun testSharedFlowEmitions() = runBlocking {
        var tick = 0
        val f: Flow<Int> = flow {
          while (tick < 10) {
            emit(tick)
            tick++
          }
        }
    
        val sharedFlow: SharedFlow<Int> = f.shareIn(this, SharingStarted.Eagerly, replay = 1)
    
        val firstSubscriber = sharedFlow.collect { Truth.assertThat(it).isGreaterThan(0) }
        val secondSubscriber = sharedFlow.collect { Truth.assertThat(it).isGreaterThan(0) }
        val thirdSubscriber = sharedFlow.collect { Truth.assertThat(it).isGreaterThan(0) }
      }
    Need help so that all three get ticks.
    w
    • 2
    • 2
  • a

    Arun Joseph

    04/03/2022, 12:51 PM
    Is there an easy way convert a
    SharedFlow
    only to emit to its first subscriber?
    m
    n
    • 3
    • 19
  • m

    Mikael Alfredsson

    04/07/2022, 9:32 AM
    Is it possible to transform from SharedFlow<typeA> to SharedFlow<typeB> without introducing a new scope? A standard transform() converts it to a Flow<typeB>
    j
    m
    • 3
    • 3
  • d

    darkmoon_uk

    04/07/2022, 2:38 PM
    Equivalent of RxJava's
    Observable.combineLatest(...)
    with n Flows to combine? There has to be a better way than this 👉 🧵
    b
    w
    • 3
    • 5
  • j

    julian

    04/07/2022, 8:59 PM
    As part of practicing coroutines and flow, I tried an implementation of
    amb/race
    where I don't allow myself to use channels directly. Or, to put it differently, I use
    SharedFlow
    instead of channels. It runs fine except that final flow collection suspends indefinitely, even after the jobs used to share the losing flows have completed and the winning flow has emitted all its items. Why? I spent a couple days trying to figure out what might be going on, without success. Here's a gist of my work, including the code I'm using to test it, and the output generated. You'll see from the output that the flow correctly emits the exception thrown by the first flow, and cancels the third flow because it emits last (so it loses the race), and all the items in the winning flow are emitted. This is a learning exercise, so I'm interested in the shortest path to getting this implementation to work. I'm not looking for a completely different implementation that works. Also happy to create a project on Github with dependencies (I use Arrow's Either data-type) if anyone's interested in running the code directly. Let me know. Thank you!
    • 1
    • 1
  • m

    Mohamed Ibrahim

    04/11/2022, 8:07 PM
    Is there an equivalent for
    Observable.compose()
    in Kotlin Flow, so we don’t break the chain, the idea is to offer only callbacks to consumer code, and internally I’m using
    Stateflow
    and
    SharedFlow
    . in Rxjava I was using
    Observable.compose()
    with Rx transformers.
    b
    • 2
    • 1
  • g

    Greg Rynkowski

    04/11/2022, 8:25 PM
    Hi all, is there any flow operator similar pairwise: https://rxjs.dev/api/operators/pairwise ?
    e
    • 2
    • 2
  • e

    enighma

    04/14/2022, 9:05 AM
    Is there a flow operator which allows me to to take the last two events and map them? or do I need to use a SharedFlow/StateFlow for that?
    w
    e
    s
    • 4
    • 11
  • s

    Sam Stone

    04/15/2022, 2:45 AM
    Why do the docs discourage the use of
    flatMapMerge{}
    ? Android SQLite has a limit of 999 params per query, so I
    window
    my params by 999, call
    asFlow
    , then
    flatMapMerge{ids->db.flowOfEntities(ids)}
    . Is that wrong?
    w
    • 2
    • 1
  • v

    Victor Collod

    04/15/2022, 2:53 PM
    Hello! Is there a way to wait for an update on a list of flows to generate another flow? for example, these could be stateflows of integers, one per resource, and I'd like to generate a flow which is the resource associated with the current maximum integer
    w
    • 2
    • 3
  • n

    Nick Williams

    04/17/2022, 10:51 AM
    Any idea why the require in awaitClose would fail? According to docs the channel is closed before the block passed into awaitClose is invoked
    fun flowFrom(api: CallbackBasedApi): Flow<T> = callbackFlow {
        val callback = object : Callback { // Implementation of some callback interface
            override fun onNextValue(value: T) {
                // To avoid blocking you can configure channel capacity using
                // either buffer(Channel.CONFLATED) or buffer(Channel.UNLIMITED) to avoid overfill
                trySendBlocking(value)
                    .onFailure { throwable ->
                        // Downstream has been cancelled or failed, can log here
                    }
            }
            override fun onApiError(cause: Throwable) {
                cancel(CancellationException("API Error", cause))
            }
            override fun onCompleted() = channel.close()
        }
        api.register(callback)
        /*
         * Suspends until either 'onCompleted'/'onApiError' from the callback is invoked
         * or flow collector is cancelled (e.g. by 'take(1)' or because a collector's coroutine was cancelled).
         * In both cases, callback will be properly unregistered.
         */
            awaitClose { 
                require(isClosedForSend) // <--- THIS FAILS
                api.unregister(callback) 
            }
        }
    e
    • 2
    • 15
  • s

    Sam Stone

    04/18/2022, 4:02 AM
    What is the most efficient way to add a List<X> to a Flow of
    List<Y>.flatMapMerge { channelFlow { send(it.toX()) } }.buffer()
    while preserving concurrency?
    n
    j
    • 3
    • 3
  • s

    Sam Stone

    04/24/2022, 5:21 PM
    Why is only
    flow2
    being called in
    flow1.map{ flow2(it) }.flattenConcat()
    ?
    flow1
    is a
    MutableStateFlow<MutableSet<Int>>
    of db entity IDs,
    flow2
    is a Flow of lists of entities, which is updated when any of the flow's entities' properties change. I am updating the properties and then calling
    flow1.emit(set)
    , but only
    flow2.onEach
    is being called, not
    flow1.map{}
    . Any suggestions?
    j
    w
    • 3
    • 4
  • m

    Mohamed Ibrahim

    04/27/2022, 9:19 PM
    How to convert pass Observable emissions to
    MutableSharedFlow<T>
    ?
    w
    j
    • 3
    • 7
  • l

    Landry Norris

    05/20/2022, 6:50 PM
    I have an interesting use case I’m looking to support. I’m currently using a MutableStateFlow of a single data class to represent the UI state. I have several video controllers that control several videos. Each one exposes the current timestamp of the video as a Flow<Double>. The user can select one video, and the seekbar should set its position based on the timestamp of the selected video. My current solution is to collect the state flow, get the current controller, and collect the position inside of that. I can then update the state based on the collected value. Is there a better way to handle this?
    m
    • 2
    • 24
  • a

    Alexander Maryanovsky

    05/23/2022, 8:42 AM
    Why does
    combine(flows, transform)
    not call
    transform
    if
    flows
    is empty? Is that intended? Seems like it would be more natural to call it with an empty array.
    e
    n
    • 3
    • 7
  • a

    Alexander Maryanovsky

    05/30/2022, 3:06 PM
    Whoever decided to have both
    Flow{ fun collect() }
    and
    Flow.collect
    (an extension function) needs to have a stern talking to.
    e
    • 2
    • 10
  • a

    AmrJyniat

    06/01/2022, 9:12 AM
    Can I save the last n values of
    sharedFlow
    and later return the value that I want, Do
    Reply
    help me in this task?
    e
    • 2
    • 1
  • a

    AmrJyniat

    06/06/2022, 2:10 PM
    Can I disable the
    distinctUntilChanged()
    default behavior when using
    shareIn()
    and
    StateIn()
    ?
    f
    d
    • 3
    • 2
Powered by Linen
Title
a

AmrJyniat

06/06/2022, 2:10 PM
Can I disable the
distinctUntilChanged()
default behavior when using
shareIn()
and
StateIn()
?
f

Francesc

06/06/2022, 3:13 PM
shareIn
does not have an implicit
distinctUntilChanged
, so just use that instead of
stateIn
if you don't want that behaviour
✅ 1
d

DALDEI

08/07/2022, 3:15 PM
you can override operator equals() to have it return false
View count: 13