Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EmberJS: Cannot read property 'typeKey' of undefined

I imagine this one should be fairly simple, but I haven't gotten to the root of the problem and I'm still learning Ember-Data.

I have two models with a hasMany relationship between them:

App.User = DS.Model.extend({

  displayName: DS.attr('string'),
  email: DS.attr('string'),
  firstName: DS.attr('string'),
  lastName: DS.attr('string'),
  location: DS.attr('string'),
  messages: DS.hasMany('message')

});

App.Message = DS.Model.extend({

  user: DS.belongsTo('user'),
  createdAt: DS.attr('date'),
  updatedAt: DS.attr('date'),
  fullText: DS.attr('string'),
  subject: DS.attr('string'),
  recipients: DS.attr('string')

});

Ember-data retrieves a user from the server, output like so:

{  
   "user":[  
      {  
         "id":"3",
         "firstName":"A",
         "lastName":"User",
         "location":"",
         "email":"[email protected]",
         "displayName":"auser",
         "messages":[  
            {  
               "id":"3",
               "user":"3",
               "createdAt":"2014-08-06 20:08:38",
               "fullText":"Here is some text",
               "recipients":"",
               "subject":"Message subject (may not be needed)",
               "updatedAt":"2014-08-06 20:08:38"
            }
         ]
      }
   ]
}

However, when Ember attempts to populate the store with this response, I get the following error:

Error while loading route: TypeError: Cannot read property 'typeKey' of undefined
    at Ember.Object.extend.modelFor (http://www.musicicons.dev/assets/packages/ember-data/ember-data.js:10667:22)
    at Ember.Object.extend.recordForId (http://www.musicicons.dev/assets/packages/ember-data/ember-data.js:10112:21)
    at deserializeRecordId (http://www.musicicons.dev/assets/packages/ember-data/ember-data.js:11116:27)
    at deserializeRecordIds (http://www.musicicons.dev/assets/packages/ember-data/ember-data.js:11130:9)
    at http://www.musicicons.dev/assets/packages/ember-data/ember-data.js:11095:11
    at http://www.musicicons.dev/assets/packages/ember-data/ember-data.js:9317:20
    at http://www.musicicons.dev/assets/packages/ember/ember.js:3428:16
    at Object.OrderedSet.forEach (http://www.musicicons.dev/assets/packages/ember/ember.js:3271:10)
    at Object.Map.forEach (http://www.musicicons.dev/assets/packages/ember/ember.js:3426:10)
    at Function.Model.reopenClass.eachRelationship (http://www.musicicons.dev/assets/packages/ember-data/ember-data.js:9316:42)

If I remove or rename the hasMany relationship from my User model, the error goes away, so somehow I think my JSON is constructed incorrectly.

like image 858
Kyle Avatar asked Dec 09 '22 06:12

Kyle


2 Answers

Update

Ember Data does support it now: Ember-data embedded records current state?

Original

Ember Data doesn't support embedded records by default, meaning your json should really be in this format (if you are finding a user by id 3):

{  
   "user":
   {  
      "id":"3",
      "firstName":"A",
      "lastName":"User",
      "location":"",
      "email":"[email protected]",
      "displayName":"auser",
      "messages": [3]
    },
    "messages":[  
     {  
       "id":"3",
       "user":"3",
       "createdAt":"2014-08-06 20:08:38",
       "fullText":"Here is some text",
       "recipients":"",
       "subject":"Message subject (may not be needed)",
       "updatedAt":"2014-08-06 20:08:38"
     }
    ]  
}

Example: http://emberjs.jsbin.com/OxIDiVU/918/edit

You can read about Embedded records here: Ember-data embedded records current state?

like image 188
Kingpin2k Avatar answered Dec 17 '22 09:12

Kingpin2k


Ember Data now supports embedded records, so all you need to do is define a custom serializer and Ember Data should accept your JSON payload as is. Here is the custom serializer that you need to define:

App.UserSerializer = DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, {
  attrs: {
    messages: {embedded: 'always'}
  }
});

This essentially tells Ember Data that 'messages' will be part of the user object graph.

If you're using ActiveModelSerializer, then it will look like this instead:

App.UserSerializer = DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {
  attrs: {
    messages: {embedded: 'always'}
  }
});
like image 26
Johnny Oshika Avatar answered Dec 17 '22 11:12

Johnny Oshika