-
Notifications
You must be signed in to change notification settings - Fork 97
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
Is it possible to not activate a staled observable when reactivating flatMapLatest? #310
Comments
It's not clear why this would be "unwanted", based on the behavior of |
Thanks for your reply. Just realized that the snippet failed to illustrate my problem. It's now updated. I don't want it because it's no longer the observable created from the latest value. Here's what I am trying to do: let loggedInUserDetails$ = loggedInUser$.flatMapLatest(user => {
if (!user) {
return Kefir.constant(null);
}
return Kefir.stream(emitter => {
user.on('detailsChange', emitter.emit); // <-- It throws an exception if the user is logged out
return () => user.off('detailsChange', emitter.emit);
});
}); |
The new snippet is probs how I'd solve it, tbh (if I understand the issue correctly). Presumably, there's something about the user data you can check to determine whether you should be subscribing to it or not (e.g. |
Thank you. The snippet above looks to work but is actually not: // initially, loggedInUser has a current value of user A
loggedInUserDetails.log("details");
// flatMapLatest creates a Kefir.stream with user A, so far so good
loggedInUserDetails.offLog("details");
// after some time, user A logs out, loggedInUser emits a `null`
loggedInUserDetails.log("details");
// before creating a Kefir.constant(null), flatMapLatest activates the previous
// Kefir.stream bound to user A, which triggers a throw The throwing is indeed out of my control. I could wrap the |
Ah, so that's caused by the |
Oh that null from loggedInUser is expected. And loggedInUser does have some other subcriber. Let's replace 1 null to avoid confusion. let loggedInUserDetails$ = loggedInUser$.flatMapLatest(user => {
if (!user) {
return Kefir.constant({});
}
// ...
}); What I think is the stream is remembered in _curSources of the AbstractPool after deactivation. |
So in general, I think all of this is expected from a "what Kefir is supposed to do" perspective. I'm not sure I can come up with a good solution without a reproducible example, as I'm having some difficulty getting my head around the intended behavior here vs what you're seeing. |
Here's a reproducible example. // library stuff
let currentUserName = null;
class User {
username = '';
detailsChangeCbs = [];
constructor (username) {
this.username = username;
}
onDetailsChange = (cb) => {
if (currentUserName !== this.username) {
throw new Error("Nope. User " + this.username + " is not logged in.");
}
cb({
username: this.username,
details: "more details"
})
this.detailsChangeCbs.push(cb);
}
offDetailsChange = (cb) => {
this.detailsChangeCbs = this.detailsChangeCbs.filter(x => x !== cb);
}
}
let userEmitter;
let loggedInUser$ = Kefir.stream(emitter => {
userEmitter = emitter;
return () => (userEmitter = undefined);
})
.toProperty(() => currentUserName ? new User(currentUserName) : null);
let login = (username) => {
currentUserName = username;
if (userEmitter) {
userEmitter.emit(new User(username));
}
};
let logout = () => {
currentUserName = null;
if (userEmitter) {
userEmitter.emit(null);
}
};
// my stuff
let loggedInUserDetails$ = loggedInUser$.flatMapLatest(user => {
if (!user) {
return Kefir.constant({ details: "nil" });
}
return Kefir.stream(emitter => {
try {
user.onDetailsChange(emitter.emit);
return () => user.offDetailsChange(emitter.emit);
} catch (ex) {
console.error(ex);
}
});
});
const onUserChange = user => console.log("Logged in user:", user);
const onUserDetailsChange = details => console.log("Logged in user details:", details);
loggedInUser$.onValue(onUserChange)
loggedInUserDetails$.onValue(onUserDetailsChange);
login("A")
loggedInUserDetails$.offValue(onUserDetailsChange);
setTimeout(() => {
logout();
setTimeout(() => {
loggedInUserDetails$.onValue(onUserDetailsChange);
}, 100);
}, 100) The outputs of observables matches what I want. Now I am trying to get rid of the exception without try/catch. Thanks |
Hi, I am looking for a way to avoid the activation of an observable created from a previous activation of flatMapLatest.
Any input would be appreciated. Thanks!
The text was updated successfully, but these errors were encountered: