No paging field for campaign_id level requests - facebook-graph-api

When requesting all adgroups or creatives for an account:
GET / adgroups?ids=act_accountid&access_token=...
the return includes a paging field, such as:
{
*id*: {
"data": [
{
...
},
...
],
"count": 1500,
"limit": 500,
"offset": 0,
"include_deleted": null
"paging": {
"next": ...
},
}
}
However, when requesting all adgroups for a campaign:
GET / adgroups?ids=campaign_id&limit=10&access_token=...
the return does not include a paging field:
{
*id*: {
"data": [
{
...
},
...
],
"count": 15,
"limit": 10,
"offset": 0,
"include_deleted": null
}
}
Is this a bug, the intended operation, a future feature, etc? While I don't have real examples of needing the paging field (currently none of our campaigns would exceed the default limit), I don't want to design code that relies on a potentially non-existent paging field.
Thanks in advance.

Are you looking at the data object of the returned result set? If so, the paging object is not a child of data, rather it is a sibling. Try running your query thru the graph API Explorer and see if at the bottom of the results you can see the paging object.

Related

Facebook Graph API does not return shares but comment count and like count are ok

I am trying to get shares, comments and likes count from Facebook graph API. Everything works great except the shares did not return in the response payload.
Here is the params I sent:
mypost_id?fields=message,shares,likes.summary(true).limit(0),comments.summary(true).limit(0)
Here is the response
{
"message": "HUAWEI WiFi Router AX3",
"likes": {
"data": [
],
"summary": {
"total_count": 2,
"can_like": true,
"has_liked": true
}
},
"comments": {
"data": [
],
"summary": {
"order": "ranked",
"total_count": 2,
"can_comment": true
}
},
"id": "103851678893717_115163661095852"
}
Here is the graph API screenshot
I've noticed that the shares parameter was marked as grey ( see in the figure above ), there might be something wrong with it.
I am using Facebook graph v13.0.
Is there anyone experiencing this issue before?
Looks like the API only returns shares, if there are any actual shares.
For posts with no shares, this is simply completely omitted from the result.
For posts that do have shares, you should get "shares": { "count": xy } in the resulting structure.

How to configure Ember-data to combine dependents with parent object?

I have following resources
Question /api/v1/questions/{questionID}
Category /api/v1/categories/{questionID}
Comment /api/v1/comments/{questionID}
Recommendations /api/v1/recommendations/{questionID}
Pattern answers /api/v1/patternanswers/{questionID}
The API is made to deliver children objects by parent object ID, and I don't see that compatible with Ember-data out-of-the-box (or without hacking, only proper configuration).
Question resource gets me JSON like this:
{
"errors": [],
"data": {
"created": 1439832769693,
"updated": 1440012378723,
"userID": 20,
"user": {
"password": null,
"created": null,
"updated": null,
"photoID": null,
"photo": null,
"email": "notsoimportant#host.com",
"emailConfirmed": false,
"phoneNumber": null,
"phoneNumberConfirmed": false,
"accessFailedCount": 0,
"id": 20,
"userName": "qwerty"
},
"categories": [], // does not exist in json
"addCategoriesIDs": [],
"removeCategoriesIDs": [],
"recommendations": [],
"removeRecommendstionIDs": [],
"patternAnswers": [],
"removePatternAnswerIDs": [],
"comments": [], //does not exist in json
"hint": null,
"version": 1,
"commonVersion": 8,
"id": 7,
"questionText": "What is your name?",
"weight": 0,
"answerType": 0,
"status": 0,
"estimatedTime": null,
"private": false
}
}
Properties "patternAnswers", "recommendations" are in the question, but "comments" and "categories" are not.
More over I don't get Question with listed properties filled with IDs of dependent objects. I wish I could get
{
"errors": [],
"data": {
"comments" : [11,12,13,14],
"categories" : [21,22,23,24],
"recommendations": [1,2,3,4],
"removeRecommendstionIDs": [],
"patternAnswers": [5,6,7,8],
"removePatternAnswerIDs": [],
"hint": null,
"version": 1,
"commonVersion": 8,
"id": 7,
....
}
}
.. but they are empty :(
I would like to configure my Question Model and Question Serializer to grab all that dependent objects asynchronously.
I would like to get everything just issuing
var QuestionModel = this.store.find('question',7);
var comments = QuestionModel.get('comments');
var categories= QuestionModel.get('categories');
var recommendations= QuestionModel.get('recommendations');
var patternAnswers= QuestionModel.get('patternAnswers');
How is it feasible?
If you want this to work out-of-the-box, you should set up your API according to ember guides (http://guides.emberjs.com/v2.0.0/models/the-rest-adapter/). That said, endpoints must be:
Question /api/v1/questions/{questionID}
Category /api/v1/categories/{categoryID}
Comment /api/v1/comments/{commentID}
Recommendations /api/v1/recommendations/{recommendationID}
Pattern answers /api/v1/patternanswers/{patternanswerID}
And payload from GET /api/v1/questions/{questionID} should look like:
{
"question": {
"categories": [], // an array of ids
"recommendations": [], // an array of ids
"patternAnswers": [], // an array of ids
"comments": [], // an array of ids
"id": Number, // question id
... // others
}
}
Otherwise, you need to change the default behavior of DS.Model or/and RESTAdapter, or use QuestionController with attached models of Category, Comment, etc. Or you can pack all things in model and setupController hooks of route represented that data.
I suggest you to answer yourself these questions:
Do you really need such a complex model at the client side? The only reason you might need model is the requirement to create/change data in that set all at once.
Can you change the API? It's better to change API in regard to REST specifications, to not maintain spaghetti at client side.
How far you can go with changing the API? There is another but similar scheme:
Question /api/v1/questions/{questionID}
Category /api/v1/questions/{questionID}/categories/{categoryID}
Categories /api/v1/questions/{questionID}/categories
It's a bit easier to configure in Ember then your version.

How is a json paginated resource supposed to look like?

With Ember Data and Jsonapi. How is a json paginated resource supposed to look like?
I built my response so it looks like:
"meta": {
"page": {
"number": 1,
"size": 5,
"total": 39
}
},
"links": {
"self": "http://localhost:3099/api/v1/articles",
"prev": null,
"next": "http://localhost:3099/api/v1/articles?page[number]=2",
"first": "http://localhost:3099/api/v1/articles?page[number]=1",
"last": "http://localhost:3099/api/v1/articles?page[number]=39"
},
"data": [
...
]
But I am not exactly sure if this is the right format. based on the explanation at http://jsonapi.org/format/#fetching-pagination
Or, are the pagination links (i.e. prev, next, first and last) supposed to be in meta.page ?
You could use ember-cli-pagination and its format to do pagination. I'm pretty sure Ember Data does not follow the JSON API spec strictly.
Based on your sample this could be a format:
{
"meta": {
"total_pages": 3,
"page": 1
},
"articles": [
{"id": 1, "title": "Hello World", "body": "More to Come"},
// ......
]
}
The request URL of this payload could be http://localhost:3099/api/v1/articles?page=1. See the API for more info.
Ember Data doesn't follow the JSON spec strictly so you should concentrate more on setting up the JSON with what ED needs. I would personally move the 'links' info into the meta tag. Otherwise Ember-Data will attempt to put them into a model called 'links', which may not be what you want. If you do intend to store those inside a separate 'links' model, then what you have is fine.

Ember - Only update fields returned in response JSON

we would like to add lazy loading functionality to our ember project, but it looks like ember will always override fields not returned by the response JSON with NULL. First I get a list of users:
GET https://example.com/users
{
"users": [
{
"id": 1,
"name": 'user1',
"email": 'email#user1.com',
"images": [],
"posts": []
},
{
"id": 2,
"name": 'user2',
"email": 'email#user2.com',
"images": [],
"posts": []
},
{
"id": 3,
"name": 'user3',
"email": 'email#user3.com',
"images": [],
"posts": []
},
]
}
This provides a minimal set of user information, with two empty hasMany relations "images" and "posts".
Now, if somebody want to see the users posts or images he would click a button which triggers the lazy loading:
GET https://example.com/userImages/1
{
"user": {
"id": 1,
"images": [1,2,3,4]
},
"images": [
{
"id": 1,
"name": "image1",
"path" "path/to/img1/"
},
{
"id": 2,
"name": "image2",
"path" "path/to/img2/"
},
{
"id": 3,
"name": "image3",
"path" "path/to/img3/"
},
{
"id": 4,
"name": "image4",
"path" "path/to/img4/"
}
]
}
To reduce traffic to a minimum, only the newly loaded information is included. After the adapter has deserialzed and pushed the new data to the store, all fields from User1 which are not included in the payload (name, email) are set to NULL in the ember store (tested with store.pushPayload('model', payload)).
Is there a possibility to update only incoming data? Or is there a common best practice to handle such a case?
Thanks in advance for your help
EDIT:
One possibility would be to extend the ember-data "_load()" function with the block
for (var key in record._data) {
var property = record._data[key];
if( typeof(data[key]) == 'object' && data[key] == null ) {
data[key] = property;
}
}
But this is the worst possible solution I can imagine.
I think what you want is the store's update method. It's like push (or pushPayload), except that it only updates the data that you give it.
Your property returns a promise and that promise returns whatever came back from the server.
foobar: function() {
return this.store.find('foobar');
}
When the promise resolves, you have two versions of the data, the one already rendered in the client (dataOld) and the one that just returned from the backend (dataNew). To update the client without removing what hasn't change, you have to merge the old and the new. Something along the lines of:
foobar: function() {
var dataOld = this.get('foobar');
return this.store.find('foobar').then(function(dataNew) {
return Ember.$.merge(dataOld, dataNew);
});
}

Is it possible to set the django-tastypie objects key?

By default, when using django-tastypie and fetching a resource list, the response is of the format:
{
"meta": {
"limit": 20,
"next": null,
"offset": 0,
"previous": null,
"total_count": 3
},
"objects": [{
"body": "Welcome to my blog!",
"id": "1",
"pub_date": "2011-05-20T00:46:38",
"resource_uri": "/api/v1/entry/1/",
"slug": "first-post",
"title": "First Post",
"user": "/api/v1/user/1/"
},
...
]
}
I've dug into the documentation and looked & looked, but I can't seem to find any kind of meta option or setting to change the "objects" key to actually describe the returned items. For example, let's say I have list of locations in one api call and a list of people in another. I'd like to be able to differentiate the key to "locations" and "people". The real reason for this is because I'm using RestKit on iOS and want to be able to set up multiple mappings.
The Resource hooks alter_* can be used to alter the structure of the data.
An example Resource using 'locations' would be:
class MyLocationsResource(ModelResource):
def alter_list_data_to_serialize(self, request, data):
data['locations'] = data['objects']
del data['objects']
return data
def alter_deserialized_list_data(self, request, data):
data['objects'] = data['locations']
del data['locations']
return data