-
Notifications
You must be signed in to change notification settings - Fork 115
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
[Code health] Verify usage of Rx side effects #78
Comments
Agree 100%. We should work towards this as we continue to implement functionality for Alpha/MVP version. Since it's not blocking, perhaps we can roll into ongoing work, and be mindful of this going forward.
Not sure about the UI part. The sole purpose of some Observables is for the UI to watch and react to changes in the view model state. If that's the case, it's hard to explain why some UI components would react to the stream, while others would be altered by side-effects. |
Note: This appears to be related to #67. |
You're right! Android's architecture and binding/livedata stuff effectively makes handling UI a non-issue for us and is the better approach. So really, the only time we might want to use side effects are for logging purposes. I also think we should avoid using side effects for kicking-off data manipulations that are external to the given stream. For example, in the EditRecord VM there are currently some side effects on stream S that, when called, set the contents of a property P on the VM--we can instead express this property's value as a stream transformation on A (and eventually as live data)--this it will still trigger the desired changes at the same time as the side-effecting set up (as values are emitted downstream). |
Just came across this in Google Rx MVVM example: They're using side effects for loading state indicator as well as errors. Arguably more readable than using a wrapper class, esp. since there's no downside to doing so in this particular case afaict. |
The state-indicator handling is pretty nifty! I'm sure there are a lot of places where we could similarly fire off a subject on subscribe. I agree that the example is very readable--it also seems to adhere to the idea of keeping non-emissions altering code in IIRC (which I may well not), at the moment there are a couple of places where we tuck away some object field changes (like set mutable live data) or other 'side-effects' into a mapped function on the stream--really it should be separated out into a separate call in a More concretely, we should refactor cases like:
to something like this instead:
That keeps our mapping functions "pure", i.e. free of side-effects, where side effect is more or less any code that amounts to This may be a non-issue. At this point I only have a vague memory of seeing these cases in the codebase, so they may not actually exist, lol. At any rate, I think dropping our |
I agree. Let's keep this in mind going forward. I'm not 100% convinced we should remove Thanks for the comments! |
Latest guidance is in our Wiki; let's identify these as we go, closing for now. |
There are some instances in the code in which we rely on
doOnNext
,doOnSuccess
and other RX side effect operators.In general, we should either avoid side effects entirely or ensure their usage is carefully prescribed.
Personally, I like treating anything that does not have to do with the direct manipulation of data (emitted items) as a side effect. For example, logging and UI changes would both be considered side effects from this perspective. I think this approach enables us to maintain clear separation between the actual 'transformation'/ data-manipulating code and 'side-effecting' code like logging.
For our purposes, we only need to treat logging as a side-effect, since display related code is handled by fragments (and ideally live-data binding). The majority of cases in which we manipulate some piece of data in a
doOn
function can be expressed using transformations instead.@gino-m
The text was updated successfully, but these errors were encountered: