Record saves, promise rejects with custom REST adapter


#1

Cross-post from SO:

I’m writing an ember-data adapter for the DreamFactory services platform and am running into an issue I think is related to my adapter.

When updating an existing record the promise resulting from model.save() is ALWAYS rejected with an error of

Assertion Failed: An adapter cannot assign a new id to a record that already has an id. <App.Event311:1> had id: 1 and you tried to update it with null. This likely happened because your server returned data in response to a find or update that had a different id than the one you sent

Thing is - the request to the REST API and the response back from the REST API have the same ID!

Request (POST)

{
    "record": {
        "id": "1",
        "title": "Sample Event",
        "date": "7/20/2013",
        "type": "success",
        "desc": "My first sample event."
    }
}

Response

{
    "record": [
        {
            "id": 1,
            "title": "Sample Event",
            "date": "7/20/2013",
            "type": "success",
            "desc": "My first sample event."
        }
    ]
}

The really weird thing is the record still updates properly both in the store AND in the database!

I have a working JSBin that illustrates the problem. My custom adapter is on GitHub. The JSBin as well as my app are using Ember 1.7.0 and ED 1.0.0-beta.9

The JSBin is attached to my personal hosted instance of DreamFactory - I haven’t done anything with it outside of allowing access from JSBin but please be gentle :slight_smile:

Here is the full updateRecord method:

updateRecord: function(store, type, record) {
	var data = {};
	var serializer = store.serializerFor(type.typeKey);
	serializer.serializeIntoHash(data, type, record);
	var adapter = this;

	return new Ember.RSVP.Promise(function(resolve, reject) {
		// hack to make DSP send back the full object
		adapter.ajax(adapter.buildURL(type.typeKey) + '?fields=*', "PUT", { data: data }).then(function(json){
			// if the request is a success we'll return the same data we passed in
			resolve(json);
		}, function(reason){
			reject(reason.responseJSON);
		});
	});
}

#2

I think your issue is that you are returning an array from a POST when you should be returning a single object.


#3

When deserializing in extract single, your payload has a record key that you leave in there. Changing your extract single to do namespacedPayload[primaryType.typeKey] = payload.record[0]; fixed the problem, but you probably want to abstract that a bit.


#4

I just saw this got answer on SO. Can you not cross post like this without cleaning up? I wasted time debugging a solved issue.


#5

For new Record only : :

the ID in your request (POST) is the problem . you must send a json like :

{
"record": {
    "title": "Sample Event",
    "date": "7/20/2013",
    "type": "success",
    "desc": "My first sample event."
  }
}

And the server must return you new ID. like :

{
"record": {
    "id": "1",
    "title": "Sample Event",
    "date": "7/20/2013",
    "type": "success",
    "desc": "My first sample event."
 }
}

#6

@terzicigor apologies - I got distracted with other projects and never circled back around to cleanup. The issue is definitely in my serializer. I will update this post again with the corrected code. Thanks!