Skip to content

Flow.concatWith #1168

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
PaulWoitaschek opened this issue May 2, 2019 · 4 comments
Closed

Flow.concatWith #1168

PaulWoitaschek opened this issue May 2, 2019 · 4 comments
Labels

Comments

@PaulWoitaschek
Copy link
Contributor

I often times need to concat two flows. In RxJava this is called concatWith.

A implementation could look like:

fun <T> Flow<T>.concatWith(other: Flow<T>): Flow<T> {
  return flow {
    collect { emit(it) }
    other.collect { emit(it) }
  }
}
@qwwdfsad
Copy link
Collaborator

qwwdfsad commented May 14, 2019

Could you please provide a use-case for this operator similarly to how you did in #437?
Just a small sample of a domain-specific problem will be enough

@jcaiqueoliveira
Copy link

jcaiqueoliveira commented Jun 21, 2019

I think that an use case can be something like that:

Processing a document where for each page its emitted a non-terminal state like "InfoNotFound".
If the entire document is processed and the info is not found its necessary to emit more one state to indicate that you have reached the end of the document.

I did something like that to process a pdf with 10 pages until find a barcode or process the entire pdf.

listOfPdfPageFlow()
     .flatMapConcat { page -> processPage(page) }
     .takeUntil {  it !is DocumentState.FoundInfo } //terminal state, no need to process more one page
     .startWith(DocumentState.Processing) // some loading to the user
     .concatWith(DocumentState.Done) // navigate, give some feedback, etc
     .onErrorReturn(DocumentState.Failed) // navigate, give some feedback, etc
     .collect {
          when(it){
                is DocumentState.Done, is DocumentState.FoundIt -> navigateToAnotherScreen()
                is DocumentState.Failed -> giveFeedbackAndNavigate()
          }
   }

where

sealed class DocumentState {
   object Processing : DocumentState() //non-terminal
   object InfoNotFound : DocumentState()//non-terminal
   data class FoundIt(val result: String) : DocumentState()//terminal
   data class Failed(val e: Throwable) : DocumentState()//terminal
   object Done : DocumentState() //terminal
}

fun <T> Flow<T>.startWith(start: T) = flow {
    collect { value ->
        emit(start)
        emit(value)
    }
}

@elizarov
Copy link
Contributor

elizarov commented Jul 16, 2019

If the one is startWith then the other should be completeWith for consistency with our terminology (coroutines are started and complete) and then both shall be added. Actually, there we already have onCompletion and if we add (currently missing) onStart operator, then both startWith and completeWith will have quite a trivial implementation:

startWith(value) = onStart { emit(value) }
completeWith(value) = onCompletion { emit(value) }

elizarov added a commit that referenced this issue Jul 17, 2019
All transformations are rewritten via (unsafe) transforms, but all of
(safe) transform, onStart and onCompletion operators collectors are safe.

Fixes #1168
@elizarov
Copy link
Contributor

In a similar vein to catch operator we strive to minimalism in operators. We don't have onErrorReturn(value), but you can use catch { emit(value) }, etc.

elizarov added a commit that referenced this issue Jul 17, 2019
* All "emitting" operators (onStart, transform, onCompletion) are moved
  to Emitter
* All transformations in Transform.kt are rewritten via (unsafe)
  transforms, but all of
  (safe) transform, onStart and onCompletion operators collectors
  are safe.
* Added migration for startWith and concatWith.
* Consistent docs for all migration functions.
* JvmMultifileClass for Migration.kt so that renamed/deprecated
  functions (when they moved there) continue to resolve.

Fixes #1168
elizarov added a commit that referenced this issue Jul 17, 2019
* All "emitting" operators (onStart, transform, onCompletion) are moved
  to Emitter
* All transformations in Transform.kt are rewritten via (unsafe)
  transforms, but all of
  (safe) transform, onStart and onCompletion operators collectors
  are safe.
* Added migration for startWith and concatWith.
* Consistent docs for all migration functions.
* JvmMultifileClass for Migration.kt so that renamed/deprecated
  functions (when they moved there) continue to resolve.

Fixes #1168
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants