Hello everyone! I don't have solid concepts on Re...
# reaktive
l
Hello everyone! I don't have solid concepts on ReactiveX yet. What I'm trying to do is to download new files from an FTP server. The sequence that I'm currently thinking of is connect -> list files from FTP -> filter out files that are already in local path -> download new files. How to do this on a ReactiveX way, without having to pass the FTP connection as a parameter and returning it as an output for the next operator? I don't think having something like this is the correct way:
Copy code
fun listFilesFromFTP(ftpConnection : Connection) : Pair<Connection, List<Files>>

connectionObservable.flapMap(::listFilesFromFTP).flapMap(::filterLocalFiles)  ... and so on...
a
Hello! You could do in the following way.
Copy code
fun downloadFiles(): Completable =
    connect().flatMapCompletable { connection ->
        listFiles(connection = connection)
            .flatMap(::filterFiles)
            .flatMapCompletable { files -> downloadFiles(connection = connection, files = files) }
    }

private fun connect(): Single<Connection> = TODO()

private fun listFiles(connection: Connection): Single<List<File>> = TODO()

private fun filterFiles(files: List<File>): Single<List<File>> = TODO()

private fun downloadFiles(connection: Connection, files: List<File>): Completable = TODO()
Or, if you need to disconnect at the end. Reaktive currently lacks the "using" operator (there is a ticket to add this operator to Reaktive). But it should be easy to add it manually meantime.
Copy code
fun <S> completableUsing(
    create: () -> S,
    dispose: (S) -> Unit,
    use: (S) -> Completable,
): Completable =
    completableDefer {
        val res = create()
        use(res).doOnAfterFinally {
            dispose(res)
        }
    }
Then you can use it as follows:
Copy code
fun downloadFiles(): Completable =
    completableUsing(create = ::connect, dispose = Connection::disconnect) { connection ->
        listFiles(connection = connection)
            .flatMap(::filterFiles)
            .flatMapCompletable { files -> downloadFiles(connection = connection, files = files) }
    }

private fun connect(): Connection = TODO()

private fun listFiles(connection: Connection): Single<List<File>> = TODO()

private fun filterFiles(files: List<File>): Single<List<File>> = TODO()

private fun downloadFiles(connection: Connection, files: List<File>): Completable = TODO()
l
oh! I see! I just have to put my operations chain inside the first flatMap. And the completableUsing is just what I need also. Thanks! 😀
👍 1