5
votes

Using latest ember and ember-data.

I have a single-page application with a list of items, and the ability to open the items in tabs. I can edit the items in the open tabs, and without commiting the dirty record, go back to the list.

If I refresh the list, I get the error:

Error: Attempted to handle event loadedData on <> while in state rootState.loaded.updated.uncommitted

This is of course because I have done a App.TestObject.find() in the list, and still have the dirty uncommitted records (opened and edited records in tabs).

My goal is to show the list with updated records, but do nothing with the uncommited records. I do not want to do a rollback on the uncommited records. Is there a best practice for this?

This is a similar question, but I do not want the records reverted to original state. This is a similar case with a fiddle, but here the rollback is the right solution.

How can I solve the fiddle if I wanted to ignore the uncommitted records when I go back to the list?

2

2 Answers

5
votes

I only have a workaround for this issue by monkey-patching DS.Model.

DS.Model.reopen({
  loadedData: function() {
    if (this.get('isDirty') === false) {
      this._super.apply(this, arguments);
    }
  }
});

Resulting the model to not to update itself when in dirty state, no matter what's in the new JSON regarding this record. The other records will update themselves just fine.

4
votes

If you don't want to monkey-patch DS.Model.loadedData, here's another solution:

App.Contact.reopenClass({
    // Results of our find() call.
    cache: null,

    // Either find our data for the first time, or refresh what we have.
    findAllWithRefresh: function () {
        if (this.cache === null) {
            this.cache = this.find();
        } else {
            this.cache.forEach(function (c) {
                // This appears to be a correct list of conditions for calling
                // refresh(), but you may need to tweak it.
                if (c.get("isLoaded") && !c.get("isSaving") &&  !c.get("isError") && !c.get("isDeleted") && !c.get("isDirty") && !c.get("isReloading")) {
                    console.log("Refreshing", c);
                    c.reload();
                } else {
                    console.log("Can't refresh", c);
                }
            });        
        }
        return this.cache;
    }
});

App.ContactsRoute = Ember.Route.extend({
    model: function (params) {
        // Note that we won't see any new records using this approach.
        return App.Contact.findAllWithRefresh();  
    }
});

Here's a working jsFiddle.

The underlying problem is that you can't safely call App.Contact.find() when there are records with uncommitted changes. This seems like a design problem in Ember Data.