sylvainpolletvillard / ObjectModel

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

Object.keys or JSON.stringify does not show all ObjectModel properties #60

Closed sohailalam2 closed 6 years ago

sohailalam2 commented 6 years ago

The ObjectModel when serialized only shows properties which were passed while creating the object. However, the created object does have the default values however they are not serialized.

How can I get all the defined properties from the model?

Compute Environment: OS: Windows 10 JS: NodeJS v9.3.0

const FileInfo = ObjectModel({
    name: String,
    size: [Number],
    creationDate: [Date],
    writable: Boolean
}).defaults({
    name: "Untitled file",
    size: 0,
    writable: true
});

let file = new FileInfo({ writable: false });

console.log(`file.name = ${file.name}`);
console.log(`Object.keys(file) = ${Object.keys(file)}`);
console.log(`JSON.stringify(file) = ${JSON.stringify(file)}`);
file.name = Untitled file
Object.keys(file) = writable
JSON.stringify(file) = {"writable":false}
sylvainpolletvillard commented 6 years ago

Hi @sohailalam2

It is acually the intended behaviour. The default properties are set on the object prototype, not the object itself. If you serialize an object to JSON then parse the JSON and pass it to the model constructor, the defaults will apply again and you will get the same object. This is needed because changing the defaults of a model should update default values on all previously created instances.

If you want the missing properties to be set at object instanciation as own properties with the default values, this is no longer "default properties", it is more like a "one-time assignment". So you can do this :

const FileInfo = ObjectModel({
    name: String,
    size: [Number],
    creationDate: [Date],
    writable: Boolean
})

FileInfo.create = function(props){
  const defaultProps = {
    name: "Untitled file",
    size: 0,
    writable: true
  }
  return new FileInfo( Object.assign(defaultProps, props) )
}

let file = FileInfo.create({ writable: false });

edit: I initially thought you were right about Object.keys, but after rereading the docs this method should only return the own properties of an object, not those inherited from the prototype. To get all the properties including those in the prototype, you can use a for..in loop

sohailalam2 commented 6 years ago

Thanks @sylvainpolletvillard for your comments.

Actually I am not worried about default properties whatsoever. My requirement is as follows -

  1. Define an object model, say FileInfo
  2. Instantiate file with some default values
  3. Serialize file and save the data into a database

The step 3 is where I am facing an issue because doing a JSON.stringify does not give the entire schema. So I was wondering how can I get the entire schema with default values (if they are not defined) and then save the values into a database.

for..in works but I wonder if this is the right way to do it!

sylvainpolletvillard commented 6 years ago

Did you try the code I posted above ? It should do what you are looking for.

sylvainpolletvillard commented 6 years ago

Closed due to inactivity