Series: CRUD 2016

CRUD 2016 pt 3-Create (and refactor)

Published on Feb 26, 2016

In the final episode of our 3-part series, we complete the CRUD operations with Create.

After that, we refactor the Create and Update operations (new and edit pages) with a helpful component- going farther than we did last year.


Links

Code

//router.js
Router.map(function() {
  this.route('monsters', function(){
    ...
    this.route('new')
  })
});
//controllers/monsters/new.js
export default Ember.Controller.extend({
  newModel: {},
  actions: {
    save(){
      let model = this.store.createRecord('monster', this.get("newModel"))
      this.set("newModel", {})
      model.save().then(()=>{
        this.transitionToRoute('monsters.monster.show', model)
      })
    }
  }
})
//components/monster-form.js
export default Ember.Component.extend({
  actions: {
    save(){
      this.attrs.save()
    }
  }
});
{{! templates/components/monster-form.hbs }}
<div class="monster-card">
  Name: {{one-way-input value=model.name update=(action (mut model.name))}}
  <br>
  Level: {{one-way-input value=model.level update=(action (mut model.level))}}
  <br>
  <img src={{model.imageUrl}} />
  <br>
  Image Source: {{one-way-input value=model.imageUrl update=(action (mut model.imageUrl))}}
  <br>
  Price (in dollars): {{one-way-input value=model.price update=(action (mut model.price))}}
</div>

<button {{action 'save'}}>Save</button>
{{! templates/monsters/monster/edit.hbs }}
{{monster-form model=model save=(action "save")}}
{{! templates/monsters/new.hbs }}
{{monster-form model=newModel save=(action "save")}}

Transcript

Hey and welcome to the third and final part of our series on building a CRUD application in 2016 with Ember.

So we’re showing it, we show a list and individual ones, and then we can edit and destroy the monsters. However we also want a way to create monsters, and that’s what we’ll do today. We’ll also, after we create the initial version, we’ll find out how to use components in order to dry up some of our code.

So first we’ll go to our router and then we’ll add in a route for new, and it’s going to be under monsters. Then in our monsters handlebars, we’ll add a link. We’ll put it in the left side but above the list of monsters. The link will be to monsters.new, and we’ll give it a tagName of button, so it looks like a button.

So if we go to the page and we click this, then you see we’ll be going to the new route, but there’s currently nothing showing there, so let’s make a handlebars template for that.

So we’ll nest that template under monsters, and then what we’re wanting is something very similar to the edit page. So we’ll go ahead and copy and paste it and we’ll change some things later, and then later in this episode we’ll dry it up with a component. But for now, here we are.

Now we need to make the new monsters controller. Once again, a lot of this can be copied from the edit monster controller, but there are some important things we’ll need to change. So first of all there’s not a model there when it’s a new model, so we’ll create an empty hash as our new model. And here we’ll replace all instances of model with newModel, so that it’s using that.

Next, we'll need to create something, so we’ll create our model using the newModel. So we’re creating a record that’s of type monster, and it has all the attributes that we’re setting here. And then we can save on this model that we’ve created, and then what we do looks very similar to what we were doing before.

So we can test whether this works fairly easily. So we’ll create our monster, and it works. But there is one problem. If we now hit ‘New Monster’, it will have saved all of that information because it’s still in the newModel hash. So we’ll go ahead and set the newModel to an empty hash whenever we’re saving it.

So we’ve got our ‘New Monster’ page working, but it does share a lot of code with the edit page, both in the controller but even more so in the handlebars. Look at this handlebars. Look at this handlebars. Very similar. So we’re going to combine that into a component that can be used by both new and edit.

So we’re going to generate a component and we’re going to call it monster-form. So first we’ll grab everything from the edit handlebars, except for the ‘Save’ button, and stick it in monster-form. And then in edit form we’ll put in a monster-form component and feed it the model. In new handlebars, we’ll be able to do something similar, but when we’re defining... when we’re putting in the monster-form component, the model will actually be newModel instead of just model.

So that’s where we left it last year, but we can now send down the action using closure actions, so we can set save to the action save, and we’ll be able to put this button in the monster-form. We’ll go ahead and do the same thing with the edit handlebars.

Then in monster-form.js, we’ll need to add in our action, our save action, and it’ll just call this.attrs.save. And here we can see that it’s working just like before.

And it may not seem as if we've saved that much code, but if we had a more complex ‘Save’ button, this would definitely be a huge savings.

And there we go. Here is our basic CRUD app. We can create, we can show, we can edit, and we can destroy.

So if you’re watching this later in 2016, then you may already have new things like routable components or one-way components, the new Glimmer components. If so, don’t worry, this stuff is still valid, it just might be deprecated. And then in 2017, I’ll create a new version that’ll update with all that stuff. I’ll see you then.

CRUD 2016

Subscribe to our mailing list