I'm trying to learn the library RxSwift
I have some code like this:
if data.checkAllIsOk()
{
[do things]
}
else
{
[show alert]
}
Now i need to update the data from the server before checking, so i have modeled a getData() that return an Observable.
My current approach is this:
getData()
>- flatMap{ (data:Data) -> Observable<Bool> in
_=0 // workaround for type inference bugs
return just(data.checkAllIsOk())
}
>- subscribeNext{ (ok) -> Void in
if ok
{
[do the things]
}
else
{
[show the alert]
}
}
>- disposeBag.addDisposable()
It works (or it should, i'm still writing it), but it feels wrong.. is there a more "reactive" way to do it? What are the most appropriate operators to use?
Maybe returning an error for “false” and use the catch block?
Update
Following the approach suggested by ssrobbi i splitted the 2 branches in 2 different subscribeNext, and used filter to select the positive or negative branch. This is the code resulting:
let checkData=getData()
>- flatMap{ (data:Data) -> Observable<Bool> in
_=0
return just(data.checkAllIsOk())
}
>- shareReplay(1)
}
[...]
checkData
>- filter{ (ok) -> Bool in
ok == true
}
>- subscribeNext{ (_) -> Void in
[do the things]
}
>- disposeBag.addDisposable()
checkData
>- filter{ (ok) -> Bool in
ok == false
}
>- subscribeNext{ (_) -> Void in
[show the alert]
}
>- disposeBag.addDisposable()
The advantage of this approach is that i can reuse only one of the two branches in other parts of the code, without rewriting the subscribe body (less duplication is always good!)
Update
After some discussions in the RxSwift slack i added the shareReplay(1), so the getData() isn't repeated.
So to be honest I'm still learning as well, and I don't have RxSwift in front of me right now (so someone correct me if I'm spewing BS), but maybe I can give lead you into the right direction.
Your solution does work, but as you said it isn't very "reactive". I think the problem is that you have your data flow set up in a way that it has to make an imperative decision on whether to show an alert or do stuff. What should happen, is that instead of getData
returning an observable, getData
should get whatever data it needs to (whether it's from a network, core data, etc), and then it should update an observable property.
For the do things: Now, you would observe that property, map it to check if it's okay, and subscribe to it like you did, check if it's true, and if it is do things. (and add disposable)
For the alert: You'd do the exact same thing, observing that same property again, but check for the opposite case and do stuff.
I think what's not super reactive about it is that you're synchronously waiting on a response from that getData()
function, which creates a scenario where you now have state, whether to show an alert, or do that extra work. They're not derived from the value stream of some other property. Showing the alert and doing things are only related to each other because you set up your code imperatively.
EDIT: Instead of checking with an if statement whether or not that's true, perhaps you could put it through a filter before subscribing instead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With