clintjhill/ember-parse-adapter

'typeKey' error in ember-data code

Closed this issue · 10 comments

I get this error when a payload of Parse Objects are received:

'Cannot read property typeKey of undefined'

After digging up the ember-data code, I managed to fix the issue by changing the following method:

function deserializeRecordId(store, data, key, relationship, id) {
if (!Model) { Model = requireModule("ember-data/lib/system/model")["Model"]; }
if (isNone(id) || id instanceof Model) {
return;
}

            var type;

            if (typeof id === 'number' || typeof id === 'string') {
                type = typeFor(relationship, key, data);
                data[key] = store.recordForId(type, id);
            } else if (typeof id === 'object') {
                // polymorphic
                /*
                 * OLD CODE
                 * data[key] = store.recordForId(id.type, id.id);
                 */
                /*
                 * Begin modification
                 */
                var ID = id.id;
                var TYPE = id.type;
                if(!ID)
                    ID = id.objectId;
                if(!TYPE)
                    TYPE = id.className;
                data[key] = store.recordForId(TYPE, ID);
                /*
                 * End modification
                 */
            }
        }

I've had this issue right form the start, but managed to 'fix' it by directly editing the ember-data code. However, I need a more permanent solution. Any ideas?

I am having the same issue and tracked the error to this same piece of code. However, I don't think it's ember-data's fault. I'm pretty sure its because the normalizeRelationships method in the parse adapter doesn't correctly normalize hasMany relationships. Ember-data is expecting id to be an id, but it is getting passed a pointer object:

{
  "__type": "Pointer",
  "className": "GameScore",
  "objectId": "Ed1nuqPvc"
}

There is some code I don't understand on line 90 of serializer.js. It looks like the correct code for normalizing the pointers in the relationship, but it's surrounded by if(options.array). I don't know why you would ever have an array option. Maybe someone else would know better?

On more investigation I see that options.relation and the similar options.array are to handle different cases with the Parse API. I didn't see that documented anywhere, but I think it should be specified somewhere in the documentation that options array or relation are necessary. With neither option set, normalizeRelationships does nothing.

Good find! Although I'm not too sure what you mean when you say that options.array and options.relation are handled the same way by the Parse API? The relational key only holds one object to declare that it's a relation while the array key holds an array of pointers. I had issues trying to use the adapter with Relations, even after stumbling across the relation option. Probably best to leave that from here and consider a separate issue ticket.

I clearly didn't proofread my last comment. What I meant was that array, and relation are options to set on your relationships. The adapter can handle each differently in order to correspond with what the Parse API is expecting:

App.Post = DS.Model.extend({
  comments: DS.hasMany('comment', {async: true, array: true}),
  tags: DS.hasMany('tag', {async: true, relation: true})
});

I see what you mean. Setting relation: true works well. I do however have this issue where on findQuery, adding an include param for array properties does not add the included records from the payload. The adapter still ends up making a separate query each time. Do you get that too?

It doesn't look like the adapter currently supports the include param.

I too hit the same issue. Tried the relation: true option too.
id.type is undefined, and results in the below text on console.
"TypeError: Cannot set property 'store' of undefined "

  } else if (typeof id === 'object') {
    // polymorphic
    data[key] = store.recordForId(id.type, id.id);

I had this same issue when using Pointers in Parse. What I did instead is using Arrays with the objectIds and then I modified the ember-parse-adapter code to update hasMany relations using this arrays instead of Pointers. I will make a pull request after trying it better.

@epintos please do! I've run into the same problem.

@camdub is exactly right - there's an array option that you should set to true on the hasMany side if your relation is backed by an array of Pointers in Parse. Then, it worked fine for me.