-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
be able to create protected or immutable observables #9
Comments
Added an experimental implementation, see the immutables branch. Simple values
Calling the setter of either foo or bar throws an error. After the mutation, Objects var coffee = mobservable.immutableProps({ coffee : 'please' });
mobservable.sideEffect(() => console.log(coffee.coffee));
// prints 'please'
var noCoffee = coffee.mutate({ coffee : 'no thanks' });
// prints 'please' (XXX!) With the last mutation, the side effect was triggered, because the Even doing A way to work around that might be to introduce a ES 7 based So these are some first thoughts. Not sure whether this is a desirable direction, because it might be confusing for users. But maybe that isn't an issue at all. The protected options is feasible in any case, as that doesn't bring a second paradigm into the library. |
This would be really useful for undo/redo stacks etc! with passing the triggering object, do you mean: var coffee = mobservable.immutableProps({ coffee : 'please' });
coffee.sideEffect((coffee) => console.log(coffee.coffee)); |
Yup, but the arguments cannot be actually passed into the sideEffect callback, since there could be potentially many objects that cause the function to be recomputed. But I think the following would be possible: var coffee = mobservable.immutableProps({ coffee : 'please' });
var coffeeHolder = mobservable(coffee);
coffee.sideEffect(() => console.log(coffeeHolder.coffee.coffee));
// update the reference of the latest state by mutating the current state.
// Cofee remains immutable, while the sideEffect will still yield the correct result
coffeeHolder.set(coffeeHolder.get().mutate({ coffee: 'no thanks'})) |
Interesting. On the protected side, would it allow me to do something along these lines? import {protectedFromJson, transaction} from 'mobservable'
import API from 'some-fictional-module'
export let state = protectedFromJson({
authenticated: false,
authenticatedAt: null,
currentUser: null,
currentUserName() {
return this.authenticated ? `${this.currentUser.firstName} ${this.currentUser.lastName}` : ''
}
})
export function login( username, password ) {
return API.doLogin( username, password )
.then( user => {
transaction(() => {
state.authenticated = true
state.authenticatedAt = new Date()
state.currentUser = protectedFromJson( user )
})
return state.currentUser
// currentUser couldn't be modified w/o a 'transaction' block
})
}
export function logout() {
transaction(() => {
state.authenticated = false
state.authenticatedAt = null
state.currentUser = null
})
}
// Example:
state.authenticated = true // Here, is a NOOP |
@mattmccray Yup exactly that. I'm not sure whether the illegal assignment should fail silently or throw. ES5 properties fail silently if not writable, so probably that should be correct behavior, combined with some logging. |
Fun experiment as it is, I don't how immutable observables could lead to something viable with a comprehensible mental model, so i'll close it for now. @mattmccray: Feel free to file transition protected observables as separate issue, those are very doable. |
Fair enough. Honestly, I'm not sure I'm really sold on true 'immutability' in JS anyway -- It's trying to force the language to do something it's not designed for. The only compelling argument I've seen has to do with object reference comparison, which is really more of a side effect of immutability than goal (abstractly speaking). I do think protected observables could be useful -- But with proper developer discipline probably not needed. I may create a new issue to discuss. |
Based on an idea by @mattmccray: https://gist.github.com/mattmccray/c5b6c69c1653b941ccd7
There are two main directions in which this can be implemented
When 'mutating' immutable items, observers should still be notified, otherwise data would not be observable anymore.
Protected could be combined with the existing
.batch
(which should be renamed to.transaction
in that case?The text was updated successfully, but these errors were encountered: