psr7-demo
psr7-demo copied to clipboard
Empty embedded models
I just ran into a situation where I have an embedded model that only sometimes has data in Firebase (i.e. it's optional). Then when the parent model is resolved in Ember and it lacks the data, there is no FP.model instance there, just null. As a result, attempts to bind to the embedded schema properties (e.g. because you want to populate those fields) result in nothing happening. For example:
Note = FP.Model.extend
content: attr "string", default: ""
author: attr "string", default: ""
Thing = FP.Model.extend
name: attr "string"
note: hasOne "note"
Now, given some data in Firebase (which I'll just represent as JSON here), taking advantage of the schema-less nature to avoid storing unnecessary data:
[{
"name": "Foo"
},
{
"name": "Bar",
"note": {
"content": "Lorem",
"author": "Twain"
}
}]
The model instance for "Foo" in Ember, rather than containing an FP.model in the note slot, with default values (or undefined, if I can left out the defaults), returns just a simple null. I would think that the model tree should fully reflect the schema so that you can immediately start binding to such properties and change them (or even display their default values).
It's possible to set a default value for the association, something like:
Thing = FP.Model.extend
note: hasOne default: -> @store.createRecord("note")
I think it's better to make this explicit, as otherwise computed property checks would fail unexpectedly:
Thing = FP.Model.extend
note: hasOne()
hasNote: Ember.computed.bool("note") # never false if note was implicitly defaulted
Maybe there could be some syntactic sugar to setup a default has one association, something like:
Thing = FP.Model.extend
note: hasOne(default: true)
That seems like the perfect thing (and I like the idea of the syntactic sugar too), but when I tried it, the default function I set up is never called (the source doesn't call getDefaultValue
when setting up a hasOne). Perhaps I mistook a suggestion of functionality for something that already exists?
Hmm it should work, I'm using it in my app but maybe there's something different about how I've got it setup.
It's getting late here so I'm going to call it a night, but I'll have a dig into it tomorrow and see if I can figure out what's going on.
Thanks for looking into it.
Sorry to bother you, but I was wondering if you got a chance to look at your setup.
Also, I noticed some strange behavior. My thing has a note, as you've seen, but also has a hasMany
called stuff
, and each one of those models can also have an optional note. If I do a toFirebaseJSON
, when none of the models have notes, the note property doesn't appear on the "thing" level, but appears as note: null
on each item in stuff
. When I fork the store, I get the exact opposite outcome: note: null
on thing
, not no note property at all on any item in stuff
.