2
votes

While building my first app with ember and ember-data I've noticed that at one point I started getting the following error when typing in an input field for a newly created model:

Assertion Failed: Cannot delegate set('notes', t) to the 'content' property of object proxy : its 'content' is undefined.

I solved this issue by adding the following code to the route:

App.LessonNewRoute = Ember.Route.extend({
    model: function() {
        return this.store.createRecord('lesson');
    } 
});

My understanding is that this error started happening when I created (instead of letting ember generate) the LessonController using ObjectController.

I'm now wondering:

  1. Is it required to use createRecord before creating a new model instance?
  2. Is this the best way of preventing this error from happening?
1

1 Answers

1
votes

As far as I understand, Your approach is good.

In order to use a model in a view, you have to have the model instance available somehow. So if you try to use content when nothing has been assigned to it, it will fail. I go around that with a different approach, but creating the record within an action handler.

For some scenarios, specially with small models, I generally create corresponding properties in the controller (sort of a viewModel approach) with an action to handle the save. Then I actually create the record in that action, passing the controller properties arguments of createRecord.

Example (totally conceptual):

...

App.Person = DS.Model.extend({
    name: DS.attr('string')
});

...  

App.PersonAddController = Em.ObjectController.extend({

    personName: null,

    actions: {
        save: function() {

            var theName = this.get('personName');

            var person = this.store.createRecord('person', {name: theName});

            person.save().then(
                 ...pointers to success and failure handlers go here...
            ).done(
                 ...transition goes here...     
            );

        }, 
        cancel: function {
            this.set('personName', null);
        }
    }

})

Then in the template, I bind the input to the controller prop rather than a model.

{{input type="text" value=controller.personName}}

With this approach, my Route#model doesn't output a blank model to be added to my store, so I don't have to deal with rollback or anything.