Search code examples
ember.jsember-data

How to manually set an object state to clean (saved) using ember-data


Explanation:

I'm using ember-data for a project of mine and I have a question that revolves around the possibility of dirtying an object and then setting its state to clean again on purpose - without commiting the changes. The scenario is this:

Say I've fetched an object via banana = App.Fruit.find('banana'); and it has a description of "Yellow fruit!". Using XHR long-polling (or WebSockets), I may receive an updated version of the object because of another user having changed the description to "A tasty yellow fruit!" at any given point in time after I fetched the original object.

Then, what I would like to do is to update the object to reflect the newly received data. For this, I've tried different approaches:

  • I've tried calling App.Store.load(App.Fruit, new_data);. First of all, this approach doesn't work and secondly, this is not really what I want. I could've made uncommitted changes to the object myself and in this case, it would be undesirable to just discard those (assuming the load() call would overwrite them).

  • I've tried looping through the new data, calling .set() - like so: banana.set('description', new_data.description); - in order to update the object properties with the new data (where applicable = not dirty). This works but it leaves the object in a dirtied state.

In order to make the object clean/updated again - and not have the adapter commit the changes! - I've taken a look at the states the object travels through. These are (at least):

  • Step 1: Initially, the object is in the rootState.loaded.saved state.
  • Step 2: Calling .set() on a property pushes it to the rootState.loaded.updated.uncommitted state.
  • Step 3: Calling App.store.commit(); returns the object to the rootState.loaded.saved state.

Therefore, I've tried to manually set the object state to saved after step 2 like so: banana.get('stateManager').goToState('saved');.

However, this doesn't work. The next time the store commits for any other reason, this maneuver produces an inFlightDirtyReasons is undefined error.

Question:

My question is: how can I manually change the state of a dirtied object back to clean (saved) again?


Solution

  • Looking at ember-data the uncommitted state has a 'becameClean' event which consequently sets the record as loaded.saved.

    This should do the trick

    record.get('stateManager').send('becameClean');