Record saves, promises rejection with REST adapter

I am writing an ember-data adapter for DreamFactory services platform and am facing a problem that I think is related to my adapter.

When you update an existing record, the promise resulting from model.save()

, always been rejected in error

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 - REST API request and response from REST API have the same ID!

Request (PUT)

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

Answer

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

It's really strange that the record still updates correctly in both the repository AND the database!

I have a working JSBin at http://emberjs.jsbin.com/mosek/1/edit that illustrates the problem. My custom adapter is on GitHub at https://github.com/ultimatemonty/ember-data-dreamfactory-adapter . JSBin as well as my app are using Ember 1.7.0 and ED 1.0.0-beta.9

EDIT

The JSBin is tied to my personal DreamFactory instance - I haven't done anything with it outside of the access permission from JSBin, but please be careful :)

* EDIT # 2 *

The code updateRecord

is available on GitHub at https://github.com/ultimatemonty/ember-data-dreamfactory-adapter/blob/master/lib/ember-data-dreamfactory-adapter.js#L106 , but here's the complete method for reference:

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);
        });
    });
}

      

+3


source to share


1 answer


The adapter / serializer used expects you to return a response without its type:

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

      

Example: http://emberjs.jsbin.com/tigiza/1/edit

You can see it here in extractSingle

where it tries to wrap the payload in another object with the specified type

EmberDreamFactoryAdapter.Serializer = DS.RESTSerializer.extend({

    extractArray: function(store, primaryType, payload) {
        var namespacedPayload = {};
        namespacedPayload[Ember.String.pluralize(primaryType.typeKey)] = payload.record;
        return this._super(store, primaryType, namespacedPayload);
    },

    extractSingle: function (store, primaryType, payload, recordId) {
        var namespacedPayload = {};
        namespacedPayload[primaryType.typeKey] = payload;
        return this._super(store, primaryType, namespacedPayload, recordId);
    },

      

Your answer looks like this:



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

      

Then the serializer runs and it looks like this:

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

      

When in fact, the serializer should look like this:

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

      

You can see from the second example, the serializer wraps it in a type, then Ember Data says hey give me an id, so it looks like event.id

undefined because it lives underevent.record[0].id

+3


source







All Articles