Search code examples
ember.jsember-dataember-old-router

How can I create a new record using Ember.js and ember-data?


I have compiled this example from various documentation and examples that I've found, but I haven't found a complete example using a Router and ember-data to simply create a new record, so this is my whack at it.

The Example

http://jsfiddle.net/dmazza/Hb6BQ/4/

I have a person (DS.Model) with a firstName and lastName.

I have a Router with index and create routes, where the create form appears in the outlet of the PeopleView.

I'm using Ember.TextField's bound to the attributes of a new Person created with App.Person.createRecord({}), as the content of PersonCreateController.

Note that I'm intentionally using separate controllers for each outlet as recommended by @wycats here: https://github.com/emberjs/ember.js/issues/1050#issuecomment-6497907

The Problem(s)

I seem to be running into the same problem over and over again. I try to use a method like App.Person.find(), and it will tell me this:

Uncaught TypeError: Cannot read property 'find' of undefined 

This will happen for:

  1. App.Person.find()
  2. App.Person.createRecord({})
  3. App.Store.find(App.Person)
  4. Several other methods (I'll update this list when I think of them)

The Question

  1. Am I even creating a new record the right way using these tools?
  2. Why might I be getting this error above? (You can see this error if you open your web inspector, pause on uncaught exceptions and make sure you are in the result( fiddle.jshell.net ) frame as opposed to )

Solution

  • With the new Ember Router introduced in pre4 I thought I'd update this answer a bit. Here's what's worked for me (Warning: CoffeeScript):

    App.Router.map ->
        @resource "posts", ->
            @route "new"
    
    App.PostsNewRoute = Ember.Route.extend
        setupController: (controller, model) ->
            controller.set 'content', {}
    
    App.PostsNewController = Ember.ObjectController.extend
        submitForm: (event) ->
            App.Post.createRecord @content
            @transitionToRoute 'posts.index'
    
    App.PostsNewView = Ember.View.extend
        controller: 'App.PostsNewController'
    

    My template looks something like this:

        <script type="text/x-handlebars" data-template-name="posts/new">
          <div class="row">
            <div class="span12">
              <form class="create-post">
                <fieldset>
                  <legend>{{_ "Post"}}</legend>
                  <label>{{_ "Post Title"}}</label>
                  {{view Ember.TextField valueBinding="postTitle"}}
                  <!-- etc. etc. -->
                </fieldset>
              </form>
            </div>
          </div>
          <div class="row">
            <div class="span12 push-right">
              <a class="btn btn-primary" {{action "submitForm"}}>{{_ "Save"}}</a>
              {{#linkTo "posts.index" class="btn"}}{{_ "Cancel"}}{{/linkTo}}
            </div>
          </div>
        </script>
    

    I'd love to hear comments on my approach.