sylvainpolletvillard / ObjectModel

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

Internal access to private properties failure - possibly due to async #101

Closed Ravenex closed 5 years ago

Ravenex commented 5 years ago

I have run into an issue with internal access to private properties when accessing this._loaded in a method called through a series of other methods. The complete output of this code is:

Dad: 5 loaded
Loading Children: daughter
Daughter: 8 loaded
TypeError: cannot access to private property _loaded
    at Proxy.lazyLoad (C:\Users\Ravenex\Documents\\test\error.js:20:10)
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:188:7)
    at Function.Module.runMain (module.js:695:11)
    at startup (bootstrap_node.js:191:16)
    at bootstrap_node.js:612:3
Daughter { ID: 'Daughter', USER_ID: 8 }

I produced a simplified single file version of the code that shows the error. I have also found that running the same code synchronously removes the error. I am not sure that's relevant or not. Both the synchronous and asynchronous versions can be found in the attached zip. This may be an additional case of issue #99.

async error.zip

sylvainpolletvillard commented 5 years ago

Yes, private access won't work with asynchronous code.

To put it simply, when using asynchronous code, at some point you are using a callback, and this callback is not a model's own method. So no private access inside this callback.

If you are using privates a lot, you may want to have a look at how they work: https://github.com/sylvainpolletvillard/ObjectModel/blob/master/src/object-model.js#L238

As you can see, private access is granted just before method call and removed just after method execution. So it only works for the own methods, synchronous part.

The common usecase for privates it to declare a getter and specific mutators to better control how a variable is mutated. The other usecase is to make it non enumerable.

Ravenex commented 5 years ago

Ok, no problem. This is an easy fix for me.

sylvainpolletvillard commented 5 years ago

I added a note to the docs to make things clearer:

Note: private properties access is granted only when using the instance own methods. Methods declared in an extended class cannot access to privates. Asynchronous callbacks do not work neither, except if these callbacks are defined as methods of the model. If this does not fit your usecase, you should probably not make these properties private.

Closing this