16

How do you paginate the request for related data? For example, if my Person has a thousand Task models attached to it if I do the following, in RESTful thinking, I would get all of them.

var tasks = person.get('tasks');

That would be way too much data. How do I force some query parameter onto the request that works behind the scenes? Ideally to an endpoint with something like this attached to the end of it.

?&offset=3&limit=3

Here is a fiddle to illustrate what I'm trying to accomplish in the IndexController. I have no idea what the "ember way" is to do paginated requests using ember-data.

dinotom
  • 4,990
  • 16
  • 71
  • 139
David
  • 10,418
  • 17
  • 72
  • 122

3 Answers3

10

It didn't exist when this question was first asked, but there is now an addon called ember-data-has-many-query that seems capable of this, at least for RESTAdapter and JSONAPIAdapter. It appears to have some quirks due to ember-data not yet supporting pagination as a first-class concept. If this makes you uneasy, there is always store.query, but this does require your API to support (in your example) a person_id filter parameter on the /tasks endpoint.

Related:

(it doesn't look like this question involved JSON API, but the discussion is relevant)

DigitalCora
  • 2,222
  • 1
  • 16
  • 24
5

As today there is still no default way to handle pagination in ember.

First we should probably look at the more simple thing, pagination of a findAll request.

This can be done with something like .query({page:3}), but leads to some Problems:

  1. This is a good solution for classic pagination, but for a infinite-scroll you still need to manually merge the results.
  2. The results are not cached, so moving forward and backward on an paginated list results in a lot of querys. Sometimes this is necessary if the list is editable, but often its not.

For the second problem I build a little addon called ember-query-cache that hooks into the store and allows you to cache the query results. A very short demo is available here.

Now if we talk about a relationship I would honestly recommend to use top level .query until you have better support from ember-data itself:

store.query('task', { person: get(person, 'id'), page: 3 }

There is nothing bad about it. You get your result and have the relationship in the other direction. It works without any hacking into ember-data as long you don't need caching, and if you need caching it requires the very few hacking I've done in my addon.

We still hope for ember-data to become fully JSONAPI complete, and that would require pagination. I think form an API perspective the best thing would be to have the ability to ask for the next and previous page on the ManyArray returned by the relationship. It would along with the JSONAPI where a next and previous link is provided. But to acomplish that now you would have to hack deep into ember-data without getting a big improvement over the top level .query, which I used successfully in many projects.

Lux
  • 17,835
  • 5
  • 43
  • 73
-2

From the Ember.js guides on using models, you can also submit a query along with the find() call.

this.store.find('person', { name: "Peter" }).then(function(people) {
  console.log("Found " + people.get('length') + " people named Peter.");
});

From the guide:

The hash of search options that you pass to find() is opaque to Ember Data. By default, these options will be sent to your server as the body of an HTTP GET request.

Using this feature requires that your server knows how to interpret query responses.

CraigTeegarden
  • 8,173
  • 8
  • 38
  • 43
  • thanks for responding. yeah, i've read that. The problem is my relationship endpoints are contained in the `links` portion of my payloads. If i were to want all `Tasks`, i would use the method above but if i want to query for a specific person's tasks, my endpoint is different, `people/$id/tasks` – David Nov 27 '13 at 15:44
  • With that type of structure it seems like the `Person` should have a `tasks: hasMany('task')` relationship, then you would access a specific person's tasks using `person.get('tasks')`? – CraigTeegarden Nov 27 '13 at 16:42
  • i may try that but tasks are polymorphic in my app. They can belong to people or companies. – David Nov 27 '13 at 17:01
  • and then i'm still left with figuring out how to access the meta data http://jsfiddle.net/Bm3Jy/13/ – David Nov 27 '13 at 17:33