add the jple toplevel namespace (or the model name) in extractArray

advertisements

I have an Ember app with a Product model. My server response is json like this (for one entry)

{
   "id": "a01dfaa0",
   "type": "computer",
   "cost": "0.50"
}

or an array of such objects

   [{
       "id": "6b2360d0",
       "type": "fridge",
       "cost": "2.50"
   },{
       "id": "a01dfaa1",
       "type": "car",
       "cost": "5.95"
   }]

In other words, there is no top level namespace (based on the model name), which Ember expects. When I return the data to the Ember app, I know I can run it through the extractArray function to add that namespace (either "product" or "products" I'm assuming) but I can't figure out how to do it. Question: how would I do that

extractArray: function(store, type, payload) {

}

Update, if I use the method proposed by the first answer, namely put this in my DS.RESTSerializer

// Override
extractArray(store, type, payload) {
  payload = this._extractPayload(Ember.String.pluralize(type.typeKey), payload);
  return this._super(store, type, payload);
},

// Override
extractSingle(store, type, payload, id) {
  payload = this._extractPayload(type.typeKey, payload);
  return this._super(store, type, payload, id);
},

_extractPayload(typeKey, payload) {
  var conformPayload = {};
  if (payload) {
    conformPayload[typeKey] = payload;
  }
  return conformPayload;
}

I get an error when my server responds with an empty array. Ember normally expects this {products : [] } when there are no records, so I'm returning [] when there are no records, but with the above extractArray method, it throws an error, saying the response from findAll must be an array, not undefined Error. When I do console.log(payload) in the extractArray function it shows an empty array []. Question, how do I modify Ember in the RESTSerializer so that it can work with json without the toplevel namespace, and, if it's not supposed to receive an empty array [] when there are no records in the db, then what is it supposed to receive?

Note, since the server expects the json without the toplevel namespace, I I send it to the server through the serializeIntoHash function of the RestAdapter to remove the namespace (the typekey) from the json (but I can't figure out how to add it back in the extractArray function)

  serializeIntoHash: function( hash, type, record, options ) {
    console.log(hash, type, record, options, "h,t,r,o");
    // Usergrid does not expect a type-key
    record.eachAttribute(function( name, meta ) {
      hash[name] = record.get(name);
    });

    return hash;
  }

Update this is the stacktrace of the error I'm getting when I run any of the suggested answers

Error while processing route: gopher Assertion Failed: The response from a findAll must be an Array, not undefined Error: Assertion Failed: The response from a findAll must be an Array, not undefined
    at new Error (native)
    at Error.EmberError (http://localhost:8080/js/vendor.js:22707:21)
    at Object.Ember.default.assert (http://localhost:8080/js/vendor.js:15408:13)
    at http://localhost:8080/js/vendor.js:64040:17
    at Object.Backburner.run (http://localhost:8080/js/vendor.js:10778:27)
    at ember$data$lib$system$store$$Service.extend._adapterRun (http://localhost:8080/js/vendor.js:70295:33)
    at http://localhost:8080/js/vendor.js:64037:15
    at tryCatch (http://localhost:8080/js/vendor.js:55993:16)
    at invokeCallback (http://localhost:8080/js/vendor.js:56005:17)
    at publish (http://localhost:8080/js/vendor.js:55976:11)

Update. This is the full adapter and serializer code (I'm not using Ember-Cli)

App.ApplicationAdapter = DS.RESTAdapter.extend({

});
// Must extend REST serializer to handle Usergrid JSON format, which is
// different from what Ember-Data expects.
App.ApplicationSerializer = DS.RESTSerializer.extend({

  extractSingle: function(store, type, payload, id) {
  var convertedPayload = {};
  convertedPayload[type.modelName] = payload;
  return this._super(store, type, convertedPayload, id);
},

extractArray: function(store, type, payload) {
  console.log(payload, "payload");
  var convertedPayload = {};
  convertedPayload[type.modelName] = payload;
  return this._super(store, type, convertedPayload);
},

});


Ember Data 1.0.0-beta.18 and up (using modelName)

serializeIntoHash: function(hash, type, snapshot, options) {
  Ember.merge(hash, this.serialize(snapshot, options));
},

extractSingle: function(store, type, payload, id) {
  var convertedPayload = {};
  convertedPayload[type.modelName] = payload;
  return this._super(store, type, convertedPayload, id);
},

extractArray: function(store, type, payload) {
  var convertedPayload = {};
  convertedPayload[type.modelName] = payload;
  return this._super(store, type, convertedPayload);
}

Here is a working JSBin that demonstrates this: http://jsbin.com/bebori/1/edit?js,output

Ember Data 1.0.0-beta.17 and lower (using typeKey)

serializeIntoHash: function(hash, type, snapshot, options) {
  Ember.merge(hash, this.serialize(snapshot, options));
},

extractSingle: function(store, type, payload, id) {
  var convertedPayload = {};
  convertedPayload[type.typeKey] = payload;
  return this._super(store, type, convertedPayload, id);
},

extractArray: function(store, type, payload) {
  var convertedPayload = {};
  convertedPayload[type.typeKe] = payload;
  return this._super(store, type, convertedPayload);
}

Here is a working JSBin that demonstrates this: http://jsbin.com/hanuwa/1/edit?js,output

I believe the problem with the other answer that looks quite similar to this one is the use of Ember.String.pluralize - I don't think that should be there.