Series: Introduction to Ember Data 2.0

Ember Data 2.0-Updating Data, Tracking Changes, and Rolling Them Back

Published on Dec 16, 2015

Not only can update your Ember Data records, but you track the unsaved changes and easily roll them back.

In this episode we go over set, rollbackAttributes, and changedAttributes, and show an imaginative use for changedAttributes


Links

Code

The most common way of updating data records is to change their either with a two-way-bound input field or to call set on the record. Then you call save on the record.

However, there are a lot of things you can do before calling save.

You can roll back the changes:

model.rollbackAttributes()

You can also see which attributes have changed:

model.changedAttributes() //=> {name: ['Rhauk', 'Rhaukky']} 

We created a method that gets those attributes in an easy-to-use way:

changedAttributesHash: Ember.computed('model.{name,level,imageUrl,price}', function(){
  let changedAttributes = this.get("model").changedAttributes();
  let usableHash = Object.keys(changedAttributes).map(function(attributeName){
    return {
      key: attributeName,
      earlierValue: changedAttributes[attributeName][0],
      currentValue: changedAttributes[attributeName][1]
    }
  })
  return usableHash
})

We can use that hash in the template:

{{#each changedAttributesHash as |attribute|}}
  {{attribute.key}}: {{attribute.earlierValue}} -> {{attribute.currentValue}}
  <br>
{{/each}}

Transcript

Hey and welcome back to Ember Screencasts. This is our 100th episode, and before we get started I wanted to say quick thank you to everyone who’s watched. It’s been a huge encouragement, especially the people who subscribed. If it wasn’t for you guys I wouldn’t have made it to 100. Here’s to another 100. Now on to some Ember data.

We’ve been working with our Monster Card example, and last episode we figured out how to destroy monsters, as well as to create new monsters. But you’ll notice that we had an ‘Edit’ page that we didn’t really talk much about. We’re going to be doing some really cool things with this Edit page in this episode.

So here are the basics of editing. We have our save action which grabs the model and then calls save. We haven’t changed anything in this action because in our template we’ve got first this two-way bound to the monster-form, and then we’ve got the inputs which are two-way bound. And so when we’re typing on the screen, it’s changing the data.

There are other ways of doing this, maybe better ways of doing this, but right now this is the simplest, is to two-way bind on inputs. And so that’s changing the model, that’s updating those attributes, and then we can call save.

We can also pass in attributes here, like you can pass in a name, and then we can use set to update stuff. And of course that won’t update on the server until we hit ‘Save’.

So to your basics of editing, you change stuff, and you call save. You can change stuff either by calling .set or by changing it in an input.

Now comes the fun part. The first thing we’ll do is create a cancel button, a button where if you made changes you didn’t like, you can just press it and they go away. The action for this easy. You just call the rollbackAttributes method on the model.

So we’ll take our example and let’s say we accidentally change this guy’s level and his image source and we can see that it’s a mistake, so we hit ‘Cancel’, and we’re back to normal.

So that’s useful but fairly easy. We’re going to be doing something more complicated and way cooler using the changedAttributes method. So the changedAttributes method, you call it and then it returns a hash, which has... for each key it has the previous attribute and the current attribute.

So what we’re going to do is when we change anything here, we’re going to have it tell us what it used to be and what it is now, so we’ll see what changes we’re making before we hit the ‘Save’ button.

Because this is a method and not a property, we’ll have to make our own property. We’ll compute it based on the four attributes that we can change, and there’s probably a better way to do this, hopefully someone of you will tell me in the comments, and then we’ll go ahead and we’ll call the changedAttributes method and get that variable.

Alright, so with that, it’s not in a very usable form. So, we’ll assign it to the usableHash, we’ll make a more usableHash, we’ll get the changedAttributes, we’ll get the keys, and we’ll map those keys and return a hash that we can use.

This hash will have three attributes, the key which is the attributeName, the earlierValue which we’ll get from the changedAttributes hash, and then the currentValue which we’ll also get from the changedAttributes hash. Then it will return the usableHash.

Then, in the handlebars template, we’ll loop over that changedAttributesHash, and we’ll go ahead and say the key, then the earlierValue, then the currentValue.

Now we’ll see this in action. We can see that there are currently no changed attributes. But if we start changing attributes, we’ll see that okay, the name has changed from Rhauk to RhaukHi, and the level has changed from 2 to 23, and we can keep on seeing these changes. So if we back out some of these changes, then it’ll no longer show them as changed, whereas other ones it will show them as changed, because this first one is an integer and that last one is a string.

So this feature is already pretty cool, but here are some more things you could do with it. You could put a ‘Cancel’ button beside each piece of data if you wanted to cancel each one individually. You could keep track of every single change, so when you hit ‘Save’, it would create another record showing that these changes were made. That’s a great way to keep track of the data that you used to have. That same implementation would also lead pretty well to a history or an Undo button.

I look forward to hearing about all the cool things you can do with these methods that I’ve showed you today, and once again to review, those methods are rollbackAttributes and changedAttributes.

In the next episode, we’ll be going over the attributes property, and we’ll see how that can be used with metaprogramming to do some really cool stuff, like here we don’t have explicit code for any of these attributes. They are all based on the attributes property. And we can change to a different model in the same route, and it’s using the same template. This is pretty magical. We’ll show you how in the pro-episode.

Introduction to Ember Data 2.0

Subscribe to our mailing list