Rxswift: Variable as observable will not send event if the observable was flatMapped to an Observable.error

Created on 13 Apr 2016  路  4Comments  路  Source: ReactiveX/RxSwift

Demonstrated by using the code in Rx.playground's Subjects section:

example("Variable") {
    enum UnknownError: ErrorType {
        case Generic
    }

    let disposeBag = DisposeBag()
    let variable = Variable(true)

    variable.asObservable()
        .flatMap { s -> Observable<String> in
            // only one line of "* true *" will be printed
            // if comment out following three lines, will print all of the expected three lines
            if s == false {
                return Observable.error(UnknownError.Generic)
            }
            return Observable.just("* \(s) *")
        }
        .doOnNext { nextVal in
            print(nextVal)
        }
        .subscribe()
        .addDisposableTo(disposeBag)

    variable.value = false
    variable.value = true
}

Most helpful comment

Hi @waterlee23 ,

you don't need harmless value, if you want to ignore error, you can just return empty sequence on error.

example("Variable") {
    enum UnknownError: ErrorType {
        case Generic
    }

    let disposeBag = DisposeBag()
    let variable = Variable(true)

    variable.asObservable()
        .flatMap { s -> Observable<String> in
            return somethingDependantOnThatCanFail(s)
               .catchError { _ in Observable.empty() } // don't do anything when error happens
        }
        .doOnNext { nextVal in
            print(nextVal)
        }
        .subscribe()
        .addDisposableTo(disposeBag)

    variable.value = false
    variable.value = true
}

All 4 comments

Hi @waterlee23 ,

this is by design. This behavior is a consequence of error propagating mechanism.

You can do

example("Variable") {
    enum UnknownError: ErrorType {
        case Generic
    }

    let disposeBag = DisposeBag()
    let variable = Variable(true)

    variable.asObservable()
        .flatMap { s -> Observable<String> in
            return somethingDependantOnThatCanFail(s)
               .catchErrorJustReturn(true)
        }
        .doOnNext { nextVal in
            print(nextVal)
        }
        .subscribe()
        .addDisposableTo(disposeBag)

    variable.value = false
    variable.value = true
}

Thank you @kzaher . The solution is good for me now, the only little imperfect side of it is that I need to choose a "harmless" value(such as empty array or empty string) for catchErrorJustReturn, since the following doOnNext is not skippable.

Hi @waterlee23 ,

you don't need harmless value, if you want to ignore error, you can just return empty sequence on error.

example("Variable") {
    enum UnknownError: ErrorType {
        case Generic
    }

    let disposeBag = DisposeBag()
    let variable = Variable(true)

    variable.asObservable()
        .flatMap { s -> Observable<String> in
            return somethingDependantOnThatCanFail(s)
               .catchError { _ in Observable.empty() } // don't do anything when error happens
        }
        .doOnNext { nextVal in
            print(nextVal)
        }
        .subscribe()
        .addDisposableTo(disposeBag)

    variable.value = false
    variable.value = true
}

Wow, thank you very much @kzaher , that's really helpful.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

hannesstruss picture hannesstruss  路  3Comments

Z-JaDe picture Z-JaDe  路  3Comments

kzaher picture kzaher  路  3Comments

apoloa picture apoloa  路  3Comments

acecilia picture acecilia  路  3Comments