Office Hours — Today, October 30

Saturday, October 27

Oct 30
7:25 PM
Mark M.
has entered the room
Mark M.
turned on guest access
7:40 PM
Aaron
has entered the room
Mark M.
hello, Aaron!
how can I help you today?
Aaron
howdy
I have four questions today, here they are. Did my best to make them clear and concise, but please take your time and ask as many questions as necessary
View paste (3 more lines)
1. If you recall, we discussed writing a zip()-like method to merge my LiveData of ClickedPostIds into the LiveData of my viewstate, to simplify my RecyclerView.Adapter which was a total cluster. I wrote a method along these lines that nearly works, except on the initial app launch. In this case, the observer on line 247 (loading the list of already-clicked posts) is called BEFORE the one on line 237 which loads the current list of posts, so what essentially happens is that line 251 compares the strings array to absolutely nothing, as postsViewStateCache is empty until the other observer fires and loads it. Thus, even if the Room database contains some IDs that should be struck through, nothing is struck through on first app launch. I think basically the problem is, unlike RxJava's zip(), my fake zip() emits half-constructed results and doesn't work the same way this diagram shows (waiting until both pieces are ready, before emitting the result) http://reactivex.io/documentation/operators/zip.html. I could use a pointer here, struggling to figure out how to accomplish this. https://github.com/ajh3/NoSurfForReddit/blob/master/app/src/main/java/com/aaronhalbert/nosurfforreddit/NoSurf
...
Mark M.
um
let's take #4 first, as it does not require me to read any code :-)
Aaron
OK
Mark M.
"I think the general conclusion here is that I should get rid of those calls and use observers instead - right?" -- well, it depends
not *everything* needs to be reactive
and, particularly in the realm of LiveData (compared to RxJava), you may run into "chicken-and-egg" scenarios where something has to be non-reactive in support of something else that is reactive (because something has to finish first)
so getValue() is not intrinsically evil or something
7:45 PM
Mark M.
now, if you are in a situation where you cannot cope with a null result, that's a more significant sign that you should be trying to react to when there is a value available
and, of course, observers are for more than just getting a non-null value -- they are there to handle changes over time
for #3, I don't think there is a canonical package structure
what you have does not strike me as being unreasonable
I might have put redditschema stuff into network
Aaron
OK, yeah
agree
Mark M.
for #2, what all calls refreshContainerChildFragment()?
is it just that observeIsUserLoggedInLiveData()-supplied LiveData?
Aaron
yes, that observer watches the user's login status and calls the method any time it changes
that's the only place
7:50 PM
Aaron
part of the reason it's so convoluted is that I think I'm not entirely trusting my own contracts, like, some of those combinations probably aren't even possible but it was easier to write all the cases than try to figure it out. but I suspect that's not the only problem
Mark M.
yeah, I can't really help with that part
and it feels a bit like you have some logic problems here, as it seems like you are creating fragments that should get assigned to fields, but then aren't obviously doing the assignment (though that might happen elsewhere)
for example, in line 73, it feels like SubscribedPostsFragment.newInstance() ought to be assigned to subscribedPostsFragment
in terms of simplification, one thing that you can do is to always create the FragmentTransaction
most of the time, you need one
Aaron
yes, true, that will help somewhat
Mark M.
so create it up front, and only do the add()/remove() calls in the if/else blocks
at the bottom, call isEmpty() on the FragmentTransaction, and if that returns false, commit() it
(it's possible that commit()-ing an empty transaction is safe -- I haven't tried that)
but otherwise, either you need to tighten up your state machine, or you need a different strategy for fragment management, or you're stuck with the rest of the code
7:55 PM
Aaron
OK, that is helpful
Mark M.
by "different strategy for fragment management", you could always have all the fragments around, and simply hide()/show() them, if they are not expensive to have hanging around
Aaron
yes, true
Mark M.
with regards to #1... you have an extra semicolon on the end of line 233 :-)
more seriously, I really don't know how to help on this sort of thing -- I can't really dive into some algorithm cold, knowing not that much about the app, and try to debug it from a code listing
Aaron
not a problem
Mark M.
this is also the sort of thing that is why I tend to use RxJava and only convert to LiveData at the end
until/unless somebody comes up with a library of operators, writing your own is going to be somewhat painful
8:00 PM
Mark M.
unfortunately, I do not see an operator library on the Android Arsenal, though one might exist and simply not be listed there
from my discussions with Googlers on LiveData, they are unlikely to add much to their Transformations class beyond the map() and switchMap() that they already have, because *they* think that you should be using RxJava for anything much beyond that
you indicated that you are writing this app as a "proof of ability" for a job search
if so, you are probably better served trying to come to grips with enough RxJava to handle this sort of thing
Aaron
OK, I will take that under advisement
Mark M.
I had hoped implementing this would be easier, and perhaps there is just some small fix that will get what you have working
but given a choice between spending N hours banging your head against a wall to get this working, and spending N hours spinning up on RxJava, choose RxJava
8:05 PM
Mark M.
you are already demonstrating enough LiveData to check off that checkbox; getting a zip() operator working is slick but is of only incremental value to an interviewer or other hiring person
particularly when compared with checking another checkbox in the form of RxJava
Aaron
yeah, I agree
Mark M.
if this project were purely some personal thing, and "proof of ability" were second place or lower in importance, fighting to get a zip operator working may be worthwhile
you could, for example, look at the RxJava implementation of Observable#zip() and see if you get some ideas
my guess is that code is nasty, but I haven't had the need to see how the RxJava sausage is made
and, if you don't have much RxJava experience, starting by looking at its zip() implementation may be... unpleasant
Aaron
yeah, I did actually peek at it, and it was not useful at the present time
OK,
got plenty to work with here, mulling some of this over but I won't keep you on the line here as I have nothing specific
8:10 PM
Aaron
one last thing that may help hack together this method - is there any way to manually force a LiveData observer to refresh itself? onChanged is a public method I guess, is there some way to just feed its current value back into it? I think that would be enough to hold it together for now
Mark M.
um, well, you could call onChanged() yourself
that feels to me, though, like you may need some other objects
basically, the observer is forwarding events to an X, and you also call something on that X in your "manual force refresh itself" scenario
rather than the observer *being* the X
Aaron
OK, yes I'll figure out something quick to hack it together as I'd like to publish it to the Play Store, but it sounds like it's time to tackle RxJava
8:15 PM
Aaron
I think it should be ready for a "code review" this weekend, so I'll pop in then and hopefully it'll be empty like today, just whatever you are able to offer at a high level during a single chat period would be awesome
I really appreciate your ongoing help. Really has been useful!
Mark M.
for that, I recommend that you prioritize stuff
Aaron
I will do that
Mark M.
based on where you want me looking
Aaron
alright - not sure if you are typing but that's all I've got for now
Mark M.
OK
8:20 PM
Aaron
have a good week!
Aaron
has left the room
Mark M.
you too!
8:25 PM
Mark M.
turned off guest access

Saturday, October 27

 

Office Hours

People in this transcript

  • Aaron
  • Mark Murphy