0
votes

I have been working to get an Emberjs front end (using Ember Data) to work with my Flask API back end. The adapter appears to be working as the api is called when the 'Listing' route is hit in the browser and I can also inspect the raw object in the network inspector, however in Ember Inspector it shows that there is a model associated, but all of the data is undefined, the route doesn't get loaded (the template doesn't show up, no data) and I continually get this error despite my efforts:

Error while processing route: listing Assertion Failed: You must include an 'id' for listing in an object passed to 'push'

The object I am sending looks like this:

{
 "data": {
   "attributes":{
     "make": "BMW", 
     "model": "640I", 
     "odometer": "11530", 
     "trim": "CPE 640I", 
     "year": "2016"
   }, 
   "id": "1", 
   "type": "listings"
  }
}

Which as far as I have seen is compliant with the json-api formatting that Ember Data needs.

Here is my code for the adapter, serializer, route, and model.

/adapters/application.js

  import DS from 'ember-data';
  export default DS.JSONAPIAdapter.extend({
    host: 'http://localhost:5000',
    namespace: 'PS/api_v1_0'
  });

/serializers/application.js

import DS from 'ember-data';
import Ember from "ember";

export default DS.JSONAPISerializer.extend({
  keyForAttribute: function(key){
    return Ember.String.dasherize(key);
  },
  serializeId: function(id) {
    return id.toString();
  }
});

/serializers/listing.js

import DS from 'ember-data';

export default DS.JSONAPISerializer.extend({

  normalizeFindRecordResponse(store, type, payload){
    return {
      data: {
        attributes: {
          exteriorColor: payload.exterior_color, 
          interiorColor: payload.interior_color,
          make: payload.make,
          mmrPrice: payload.mmr_price,
          model: payload.model,
          odometer: payload.odometer,
          trim: payload.trim,
          year: payload.year,
        },
        id: payload.login,
        type: type.modelName,
      }
    };
  }
});

/models/listing.js

import DS from 'ember-data';

export default DS.Model.extend({
  exteriorColor: DS.attr('string'),
  interiorColor: DS.attr('string'),
  make: DS.attr('string'),
  mmrPrice: DS.attr('string'),
  model: DS.attr('string'),
  odometer: DS.attr('string'),
  trim: DS.attr('string'),
  year: DS.attr('string'),
});

/routes/listing.js

import Ember from 'ember';

export default Ember.Route.extend({
  model(){
    return this.store.findRecord('listing', '1');
  }
});

I feel like I have tried everything to try and shape the JSON to get serialized by Ember Data but I have hit a wall and cannot find any other related questions - anyone have any idea how to tackle this?

1
In normalizeResponse you have id: payload.login. I don't see login anywhere in your post except there. Could it be a typo, or are you assigning an undefined property to the id?Pedro Rio
Ah good point - I was following a tutorial to set up Ember and that is what the example had - what should it be in this case? payload.id?Cameron Phillips
I think so, it should be payload.id. In case it doesn't work, I would suggest a console.log(payload) on normalizeFindRecordResponse and check where the ìd` property is inside the payloadPedro Rio
ok I had to change it to: id: payload['data'].id and the attributes were addressed using: exteriorColor: payload['data']['attributes'].exterior_color Much appreciated, thank you very much!Cameron Phillips
Cool, glad I could help. I would suggest you post that knowledge as a response and accept it. Or edit your question and place the answer there :)Pedro Rio

1 Answers

0
votes

The problem was two-fold: In the serializer I was accessing the wrong variable for the id, payload.login rather than payload['data'].id. Also, I was not indexing into the payload object for the attributes values for the attributes.

My new serializer looks like this:

/serializers/listing.js

import DS from 'ember-data';

export default DS.JSONAPISerializer.extend({
  normalizeFindRecordResponse(store, type, payload){
    //console.log(payload['data']['attributes']);
    return {
      data: {
        attributes: {
          exteriorColor: payload['data']['attributes'].exterior_color, 
          interiorColor: payload['data']['attributes'].interior_color,
          make: payload['data']['attributes'].make,
          mmrPrice: payload['data']['attributes'].mmr_price,
          model: payload['data']['attributes'].model,
          odometer: payload['data']['attributes'].odometer,
          trim: payload['data']['attributes'].trim,
          year: payload['data']['attributes'].year,
        },
        id: payload['data'].id,
        type: type.modelName,
      }
    };
  }
});