LiveEvent: Observer registered after LiveEvent already has value is not executed
If the LiveEvent’s setValue is called before observe and there is no observer to consume the event the next registered observer is not receiving the event as well because pending is by default false.
This is maybe a deliberate decision but I find it a huge weakness of the design.
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Comments: 21 (9 by maintainers)
This is related to the rejected PR I posted a while back: https://github.com/hadilq/LiveEvent/pull/24
I still consider it to be a bug, especially given how many people continue to run into this situation. The emitter shouldn’t care about the order of observers but
¯\_(ツ)_/¯I would disagree that it’s not an event in the definition of “single live event”. I would also argue that’s actually desirable to send an event for a future observer to see. Otherwise there is a coupling of the lifecycles between the observer and the emitter that I don’t think should exist. (The emitter has to know that there’s no observer yet and it’s not safe to emit.)
Say during view model initialization you want to show a toast, send a broadcast or a push notification or any other action that should happen just once. (Perhaps some early error condition was noticed.) It’s very conceivable that the view model could emit an event well before the observer has started to consume the events.
This situation can happen not only at view model initialization time but also during configuration change if things are timed just right. The observers stop observing and for a very brief moment it’s possible to emit a value before the new observers start observing.
The first condition, emitting during view model initialization, is “solved” by holding a pending event until the first observer consumes it. The second condition, emitting during a brief configuration change window, is not solvable without moving to something like channels.
@nikhiljainlive Thank you for sharing details. This problem happens because in
initof VM noLiveDatais obsereved yet. Personally I wouldpostit as you did, but it may really be a problem. I need to think more guys.I also think this should be supported (that’s why I created the PR) but well… I understand the other points as well. Anyway post is working for you because it is asynchronous and your observer make it to register in the meantime. But I wouldn’t take this “luck” for granted as it can be unpredictable.
Please review https://github.com/hadilq/LiveEvent/pull/42
@hadilq I am observing the LiveEvent in my Activity’s
onCreatemethod only. Refer below for a detailed explanation of my issue. I have a ViewModel class in which there are two properties like shown below:And, in ViewModel
initblock, I am loading the user by calling theloadCurrentUserfunction from some data storage. This later on sets theSuccessevent orFailureevent when the user is loaded or any failure occurs. Refer to the code snippet shown below:The
currentUserLivedata is then observed at MainActivityonCreatemethod.Issue: The problem is the
Loadingevent is never emitted when I set the value to LiveEvent by calling_currentUser.value = Loading(setValue method). But when I set the value in LiveEvent by calling_currentUser.postValue(Loading)(postValue method), the observer receives the Loading value even if it was not registered when the value was posted. So, I see different behaviors when usingsetValueandpostValuewith the LiveEvent.