Redsandro
Redsandro

Reputation: 11366

Ember Data: When do I use findAll() over query()?

This is the pattern I find myself running into:

I start making an app, and I use findAll() to get a list of [something random].

Once the app is being tested with serious data, the number of random resource instances will grow. I need to limit the number of resource instances on screen. I need to start paginating them. For this I need query string support. E.g. page[offset].

So findAll(criteria) is replaced by query(criteria, querystring).

This is a pattern so much that findAll() is starting to look like a development placeholder for query() to be used later.

I'm probably misunderstanding the use for findAll(). Is it true findAll() cannot use pagination at all (without customizing adapter code)? Can someone explain in what cases findAll() should be used?

Upvotes: 2

Views: 2755

Answers (3)

runspired
runspired

Reputation: 2693

If you want "all" record of a type I would recommend using query + peekAll, this is more or less what findAll does under the hood but without various timing issues / freshness issues that findAll is subject to.

query is generally a much better API because it lets you paginate, and most apps with data of any consequence eventually hit a point they are forced to paginate either for rendering concerns or data size concerns.

Upvotes: 2

Kevin
Kevin

Reputation: 309

To expand on Jean's answer, findAll does just that, finds all! If you had entities such as "post types" where you have [advertisement, blog, poem], findall makes sense, because you are pulling these 3 things all the time (for example in a "post creator").

Query is more precise. Say You had an api returning every car you have ever seen. Say you had a "car" model with properties "color" and "bodyStyle" You could use:


// find all red cars -> /cars?color=red
store.query('car', {color: 'red'});

// find all cars that are coupes -> /cars?bodyStyle=coupe
store.query('car', {bodyStyle: 'coupe'});

To your question on pagination, this is typically implemented on the API. A popular pattern is to accept/return "page" and "count" properties. These are typically found in an API payload's "meta" property.

So if you wanted to look through all cars you know of/have in your database:

// find first 10 cars -> /cars?count=10&page=1
store.query('car', {count: 10, page: 1});

// on the next page, find the next 10 cars -> /cars?count=10&page=2
store.query('car', {count: 10, page: 2});

It is worth nothing that to further your own research you should look into query parameter binding on controllers to ease the labor needed to implement a solution like this.

https://guides.emberjs.com/release/routing/query-params/

In the examples in that link you can see how you can transition to routes and use the query parameters in your store requests to fetch relevant data.

In short, findAll() is great for finding a finite set of easy to represent information, typically types of entities.

query() is great for any filtered set of results based on a criteria, as you mentioned.

Happy Coding :)

Upvotes: 2

Jean-Philippe Roy
Jean-Philippe Roy

Reputation: 4812

I personally use the findAll method for fetching data that appears in various drop-downs and short lists that cannot be filtered by the user. I use query and queryRecord for pretty much everything else.

Here are a couple of particularities of findAll that can be misleading:

  • findAll returns all of the records present in the store along with the data that is fetched using the record's adapter.
  • The return of findAll is two-fold, firstly you will receive the content of the store and then it will be refreshed with the data fetched using the adapter, this behavior can be overridden using the reload flag.

Upvotes: 4

Related Questions