I'm working on an Ember application that aggregates content from Facebook's Graph API and Rails API. Since I wrote the Rails API and have control over the JSON format, I've had no issues getting my Ember application to query and serve that content. However, I am having some difficulty normalizing the Facebook Graph API content.
As an example, here's some of the Feed JSON that the Facebook API serves:
{
"data": [
{
"id": "604231966385537_765079483634117",
"type": "link",
"message": "They're watching you...",
"from": {
"name": "Kristian Twombly",
"id": "10154089935544635"
}
},
{
"id": "604231966385537_765057943636271",
"type": "status",
"message": "The boss's new ride. He saw mine and had to have one.",
"from": {
"name": "Walter Johnson",
"id": "10206908914060788"
}
},
{
"id": "604231966385537_764751447000254",
"type": "photo",
"message": "Found 1 at Target Apple Valley",
"from": {
"name": "Quentin Waterkamp",
"id": "10210042929332132"
},
"comments": {
"data": [
{
"created_time": "2016-09-01T01:33:55+0000",
"from": {
"name": "Riley Richardson",
"id": "1189835384423610"
},
"message": "Are these rare to find or something?",
"id": "764829800325752"
},
{
"created_time": "2016-09-01T04:33:44+0000",
"from": {
"name": "Quentin Waterkamp",
"id": "10210042929332132"
},
"message": "seems to be I was also at a Walmart today and didn't see one and the other Target in Apple Valley didn't have any the other day.",
"id": "764893193652746"
}
],
"paging": {
"cursors": {
"before": "WTI5dGJXVnVkRjlqZAFhKemIzSTZAOelkwT0RJNU9EQXdNekkxTnpVeU9qRTBOekkyT1RNMk16VT0ZD",
"after": "WTI5dGJXVnVkRjlqZAFhKemIzSTZAOelkwT0Rrek1Ua3pOalV5TnpRMk9qRTBOekkzTURRME1qUT0ZD"
}
}
},
}
],
"paging": {
"previous": "http://ift.tt/2cfyf2d",
"next": "http://ift.tt/2bVdHOc"
}
}
Given that the root element is data
, I originally assumed it was being served in JSON API spec. However, the absence of an attributes
key means the default Ember JSONAPISerializer does not work without some modification. Conversely, the presence of the data
key means JSONSerializer does not parse the JSON correctly either.
I've had little luck getting the JSON to serialize correctly for all objects. If I remove the comments
attribute on /app/models/facebook-photo.js
, I can get the top-level objects (like Photos, Links, Statuses) populated (I confirmed this using Ember Inspector in Chrome). However, I am unable to serialize the embedded hasMany
relationship for comments
. I'm currently getting the following error when I attempt to run my Ember application:
extractembeddedhasmany cannot read property 'id' of null
Can anyone help me understand how to correctly normalize the JSON from the Facebook API? In addition, how can I correctly configure the hasMany
relationship for comments
?
For reference, here's my latest code (I've only included the code for facebook-photo
for simplification):
PLEASE NOTE: I'm using the modelNameFromPayloadKey
and payloadKeyFromModelName
serializer methods already, since my models for the Facebook API have 'facebook-' appended to the type name (model names were conflicting with my other API's types).
/app/routes/index.js
import Ember from 'ember';
export default Ember.Route.extend({
model() {
return Ember.RSVP.hash({
facebookFeedObjects: this.get('store').query('facebook-feed', {
fields: 'id,type,message,from,comments',
access_token: '1333570303337296%7CssnHtq9p3DuFAxX23XRx7Dc1reQ'
})
});
}
});
/app/adapters/facebook-feed.js:
import Ember from 'ember';
import DS from 'ember-data';
export default DS.JSONAPIAdapter.extend({
host: 'http://ift.tt/2cfyOJd',
namespace: '604231966385537',
pathForType: function(type) {
return 'feed';
}
});
/app/models/facebook-photo.js:
import Model from 'ember-data/model';
import attr from 'ember-data/attr';
import { belongsTo, hasMany } from 'ember-data/relationships';
export default Model.extend({
message: attr(),
comments: hasMany('facebook-comment', { polymorphic: true })
});
/app/serializers/facebook-feed.js:
import DS from 'ember-data';
export default DS.JSONAPISerializer.extend({
modelNameFromPayloadKey(key) {
let withPrefix = 'facebook-' + key;
return this._super(withPrefix);
},
payloadKeyFromModelName(modelName) {
let type = this._super(modelName);
return `${type.replace('facebook-', '')}`;
}
});
/app/serializers/facebook-photo.js:
import DS from 'ember-data';
export default DS.JSONSerializer.extend(DS.EmbeddedRecordsMixin, {
modelNameFromPayloadKey(key) {
let withPrefix = 'facebook-' + key;
return this._super(withPrefix);
},
payloadKeyFromModelName(modelName) {
let type = this._super(modelName);
return `${type.replace('facebook-', '')}`;
},
attrs: {
comments: { embedded: 'always' }
}
});
/app/templates/index.hbs:
<h3>Facebook</h3>
<ul>
<li>
<h4></h4>
<ul>
<li></li>
</ul>
</li>
</ul>
Aucun commentaire:
Enregistrer un commentaire