sylvainpolletvillard / ObjectModel

Strong Dynamically Typed Object Modeling for JavaScript
http://objectmodel.js.org
MIT License
467 stars 30 forks source link

Possibility to override conventionForPrivate on specific models #84

Closed gotjoshua closed 6 years ago

gotjoshua commented 6 years ago

Is it possible to override a convention for a single property? Or to override the convention for all properties of a specific class that extends ObjectModel?

Context: I am using Object model with MongoDB, which uses a string _id on each record. I need to have access to this when casting/cloning/transforming objects.

Related to this issue: https://github.com/sylvainpolletvillard/ObjectModel/issues/48

I would love it if the documentation could be provided: http://objectmodel.js.org/#doc-private-and-constants I'd also be happy to provide specific examples and/or links to codepens once i understand how it works...

sylvainpolletvillard commented 6 years ago

Yes, that's why these are in Model.prototype, you can override it as you want for each model or subclass of model.

const MyModel = ObjectModel({ const_x: Number });
MyModel.conventionForConstant = key => key.startsWith("const_")

let m = MyModel({ const_x: 12 });
m.const_x = 42 // TypeError: cannot modify constant const_x

To override the convention for a single property, just use a if condition in the convention function.

I saw your comment in the other issue, I will update the docs today

sylvainpolletvillard commented 6 years ago

I updated the docs and also pushed a new minor version that makes the access to private variables more strict (no async method access allowed).

gotjoshua commented 6 years ago

Thanks! It seems that the new strictness broke something that I was doing, namely nesting an ObjectModel within another.

pseudo-code:

ModelWithPrivates = ObjectModel({
 __myPrivate:ObjectModel;
})

ContainerModel = ObjectModel({
 innerModelwithPrivates: ModelWithPrivates
}

instantiating a ContainerModel threw an access to private error even though the ModelWithPrivates instance was already instantiated and was just being passed in as a property.

I just disabled privates on the ContainerModel for now... when i have more time i could make a more precise bug report... for now its just a heads up.

sylvainpolletvillard commented 6 years ago

Are you trying to access a private property from the parent ContainerModel ? That could be the issue. The change I made in the last minor release was quite important, because it fixes a bug where a model could be "stuck" in access granted mode, and all private variables could be accessed freely. So some unauthorized operations are no longer possible. If you manage to reproduce the problem on a simple example, please open a new issue, that could really help me.

sylvainpolletvillard commented 6 years ago

Now that #87 is fixed, can I close this ?

gotjoshua commented 6 years ago

yep, thanks!