dimanche 3 juillet 2016

Ember Data Edit After Create "Error: Attempted to handle event `didCommit` on

In the app I'm working on, hitting enter creates a new entry and focuses the title field, letting the user immediately start typing. The changes to that field are automatically persisted with a debounced save. Generally this works well, but if I start typing too quickly, I'm getting the following error:

Attempted to handle event `didCommit` on <app@model: ...> while in state root.loaded.updated.uncommitted.

(I've included the full error & traceback at the bottom)

The record does appear to be properly persisted to the server (Firebase through the EmberFire adapter), but there is other weirdness with the app from that point on (presumably because that iteration of the run loop blows up before completing).

To see what's up, I've attached observers onto the model's currentState.stateName and title fields. For a create-and-save without error, the record passes through the following states:

      [Press Enter; Pause]
               |
               V
 root.loaded.created.uncommitted
               |
               V
<title observer fires with blank>
               |
               V
   root.loaded.created.inFlight
               |
               V
       root.loaded.saved
               |
               V
        [Type in title]
               |
               V
root.loaded.updated.uncommitted
               |
               V
<title observer fires with value>
               |
               V
  root.loaded.updated.inFlight
               |
               V
       root.loaded.saved

When the error appears, the process looks like this:

 [Press Enter & type immediately]
               |
               V
 root.loaded.created.uncommitted
               |
               V
<title observer fires with blank>
               |
               V
   root.loaded.created.inFlight
               |
               V
[title observer fires with value]
               |
               V
       root.loaded.saved
               |
               V
root.loaded.updated.uncommitted
               |
               V
        <Error appears>
               |
               V
  root.loaded.updated.inFlight
               |
               V
       root.loaded.saved

My initial thought was that the error was being caused by the second save starting before the initial creation is complete, but the error happens in root.loaded.updated.uncommitted -- before the record enters root.loaded.updated.inFlight. I'm pretty sure this means the problem is caused by the actual editing of the field, not the call to save() the record.

Edit: Indeed, completely removing the saving of the title doesn't appear to have any effect. That seems to indicate the problem really does stem just from editing the field.

Looking at the traceback (below), it isn't obvious what is causing the didCommit event. I was wondering if my problem is the fault of EmberFire for calling didSaveRecord() while the model is in the wrong state, but searching the EmberFire codebase doesn't turn up any calls to didSaveRecord() whatsoever so that doesn't appear to be the issue.

I'm Is this just the as-designed behavior of Ember Data? If so, it seems like a pretty serious limitation that I haven't seen mentioned anywhere.

The first workaround that comes to mind is to buffer writes to the field until the model is in a "writable" state...except I've never seen any of the official Ember examples do that.

Is that the correct (or at least a reasonable) solution?

If so, what constitutes a "writable" state? Anything other than inFlight? (which I can just check for with the isSaving flag, right?)

And if not, is there another officially-recommended pattern to deal with this?

Full error/traceback:

ember.debug.js:31352 Error: Attempted to handle event `didCommit` on <app@model:task::ember965:-KLmwiGUhqrUW_CiRGb4> while in state root.loaded.updated.uncommitted. 
    at new Error (native)
    at Error.EmberError (http://ift.tt/29ovSfR)
    at InternalModel._unhandledEvent (http://ift.tt/29hJ9Um)
    at InternalModel.send (http://ift.tt/29ovspP)
    at InternalModel.adapterDidCommit (http://ift.tt/29hJ82J)
    at didSaveRecord (http://ift.tt/29ovFcq)
    at http://ift.tt/29hIH8T
    at Object.Backburner.run (http://ift.tt/29ovrlL)
    at _adapterRun (http://ift.tt/29hIYbG)
    at http://ift.tt/29ovy0q
onerrorDefault  @   ember.debug.js:31352
exports.default.trigger @   ember.debug.js:52095
(anonymous function)    @   ember.debug.js:53346
Queue.invoke    @   ember.debug.js:333
Queue.flush @   ember.debug.js:397
DeferredActionQueues.flush  @   ember.debug.js:205
Backburner.end  @   ember.debug.js:560
(anonymous function)    @   ember.debug.js:1126




Aucun commentaire:

Enregistrer un commentaire