Skip to content

Changes to `add`

Compare
Choose a tag to compare
@jondayton jondayton released this 07 Apr 15:57
4dc7e2d

store.add has been very inconsistent in the past. First, it accepted any properties. Second, it would override relationships as simple properties. This could lead to some strange situations.

Consider a basic model Todo with relationships Category and Note

class Category extends Model {
  static type = 'categories'
}
class Note extends Model {
  static type = 'notes'
}
class Todo extends Model {
  static type = 'todos'
  @attribute(String) title = ''
  @observable highlighted
  @relatedToMany notes
  @computed get capTitle () {
    return this.title.toUpperCase()
  }
}

store.add could be used to set attributes, but everything else (relationships, computed properties, and non-defined properties) would be set as an unobserved properties. When accessing the object, these would be returned as mishmash of observed attributes and properties, and unobserved properties.

const todo = store.add('todos, {
  title: 'Take out trash',
  assigneeName: 'Me',
  highlighted: true,
  notes: [{ id: '1', type: 'notes' }],
  category: store.getOne('categories', '1'),
  capTitle: 'Take in Trash'
})

$> todo.title
=> Todo {
  title: 'Take out trash',             // observed attribute
  highlighted: true,                   // observed property (will not be serialized)
  assigneeName: 'Me',                  // unobserved text (not defined as an attribute)
  notes: [{ id: '1', type: 'notes' }]  // unobserved array with an object (relationship definition is overridden)
  category: Category { id: '1' }       // unobserved Category object (relationship definition is overridden)
  capTitle: 'Take in Trash'            // unobserved text (computed property is overridden)
}

With these changes, add will work differently:

  • it accepts attributes as well as relationships, and sets them correctly
  • relationships can be passed as either the id and type of an object, or the object itself
  • it will not accept anything that is not an attribute or a relationship
const todo = store.add('todos, {
  title: 'Take out trash',
  assigneeName: 'Me',
  highlighted: true,
  notes: [{ id: '1', type: 'notes' }],
  category: store.getOne('categories', '1'),
  capTitle: 'Take in Trash'
})

$> todo.title
=> Todo {
  title: 'Take out trash',          // observed attribute
  highlighted: undefined,           // observed property, can only be set directly (not by using `add`)
  assigneeName: undefined,          // unobserved property, can only be set directly (not by using `add`)
  notes: [Note { id: '1' }],        // observed relationship array with a Note object
  category: Category { id: '1' },   // observed relationship with a Category object
  capTitle: 'TAKE OUT TRASH'        // computed property (cannot be overridden)
}