Skip to content
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

Primitive Map Type #10

Open
austinkelleher opened this issue Jan 15, 2018 · 4 comments
Open

Primitive Map Type #10

austinkelleher opened this issue Jan 15, 2018 · 4 comments

Comments

@austinkelleher
Copy link
Member

austinkelleher commented Jan 15, 2018

I think that having a Map primitive would be useful. Example:

const Map = require('fashion-model/Map')
const Model = require('fashion-model/Model')

const Car = Model.extend({
  properties: {
    id: String,
    name: String
  }
})

const CarMap = Map.create({
  key: String,
  value: Car,
  // Only required if the "value" is a Model and if you want to 
  // pass an array instead of an object upon "wrap"/"new"
  keyProperty: 'id',
  prototype: {
    getCarById (id) {
      return this.get(id)
    },
   deleteCarById (id) {
     return this.delete(id)
   }
  }
})

const Person = Model.extend({
  properties: {
    name: String,
    cars: CarMap
  }
})

const person = Person.wrap({
  name: 'John',
  cars: [new Car({ id: 'abc123', name: 'Tesla' })]
  // Also passing a standard key/value pair object is supported:
  //
  // cars: { 'abc123': new Car(...), ... }
})

console.log(person.getCars()) // { 'abc123': { id: 'abc123', name: 'Tesla' } }
console.log(person.getCars().getCarById('abc123')) // { id: 'abc123', name: 'Tesla' }

Thoughts @philidem?

@philidem
Copy link
Collaborator

philidem commented Jan 15, 2018 via email

@austinkelleher
Copy link
Member Author

The whole reason for wanting this features is to be able to do runtime validation on the key/value for what is set in the Map. If we rely on the built-in implementation of Map, we will not get those guarantees. Additionally, if we clean a model that is using a standard JS Map property, the subsequent model clean implementations will not get called.

@philidem
Copy link
Collaborator

Oh, I read the original proposal too quickly. I do think we should try to provide a way for not having to create a Map subtype.

Maybe this instead:

const Person = Model.extend({
  properties: {
    name: String,
    cars: {type: Map, valueType: Car}
  }
})

@philidem
Copy link
Collaborator

If a property is a Map type then we can automatically generate set(...) method that can assist with type coercion. We would need to create a wrapper around the underlying Map object.

For example:

person.getCars().set('blah', {year: 2018, make: 'Tesla', model: 'Model 3'}) // second argument would be coerced into a car

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants