In our app we just added a search & pagination function to most of the sites. This means we can't use findAll() anymore and instead use query. But this also means we can't have the nice background-reload behaviour and so we lose a lot of the end-user performance.
I know that it makes sense for query to have no caching behaviour, but as in our case (and I guess many more) it would increase performance and creates a better UX.
What's the approach from ember-data here? Should we build our own caching behaviour or is it something that would be interesting in ember-data itself? If so, I'd like to try creating a PR.
Hi @nicolas-dular. I marked this issue for for discussion at the next Ember Data weekly meeting.
Hey @nicolas-dular,
this has been discussed in this weeks' team meeting. You can use update() on the result of a store.query(): this will re-fetch the query and update the content of the array with the result. See this ember-twiddle for an example. Does this help with your use case?
Adding a hook like shouldReloadQuery() has been brought up in #1966, but it hasn't been added because we want to explore use cases for such a method first. If update() doesn't work for you, can you provide such a use case?
@nicolas-dular did you have a chance looking at update() being helpful for your use case?
@nicolas-dular I am going to close this as I think update() will solve your use case. Feel free to reopen...
@pangratz The OP mentioned the loss of background-reload behavior and less performance when switching from findAll to query. I am pretty sure he means too many unnecessary queries.
In that scenario, how does update() on the result of a store.query() to re-fetch contents solve his problem? I am going through something similar and I don't understand.
I looked at #1966 (@jamesdixon brought up exactly this same issue) where you suggested a proof-of-concept for caching. However, we would need something way simpler: just a shouldReloadQuery hook – exactly like shouldReloadAll and shouldReloadRecord which do not implement any caching logic. The client implements the caching logic.
For findAll its shouldReloadAll hook is called here: https://github.com/emberjs/data/blob/master/addon/-private/system/store.js#L1518 and it's three lines of code.
Analogously, would it be possible to wrap the call for query (here: https://github.com/emberjs/data/blob/master/addon/-private/system/store.js#L1169) in a similar hook shouldReloadQuery?
Shall I create a PR with those changes? Thanks!
In that scenario, how does update() on the result of a store.query() to re-fetch contents solve his problem? I am going through something similar and I don't understand.
update() on a result of a store.query will do a background reload. You can continue to show the contents if the query in the template and show an indicator based on the isUpdating flag. So I would say a background reload for an existing query is already possible.
Analogously, would it be possible to wrap the call for query (here: https://github.com/emberjs/data/blob/master/addon/-private/system/store.js#L1169) in a similar hook shouldReloadQuery?
Shall I create a PR with those changes? Thanks!
What would the arguments be for that hook?
The problem is that we are not storing all the store.query calls within Ember Data. And that's why there is no shouldReloadQuery() hook on the adapter, since it is not clear what the arguments are. We can't pass a previous query, because we don't know if there was a previous store.query call for the specified query params. Makes sense?
Also, is a query of { age: 50 } the same as {Â query: "50" }? This is very app specific and might differ from each use case.
At the moment your best bet is to do the caching yourself.
That's why there is no caching build in in Ember Data - yet. Maybe you can create an RFC and propose how you would implement such a behavior and by this get a discussion going? That would be much appreciated!
Hey @pangratz, thanks! I think there is a misunderstanding. While I am not very familiar with Ember Data internals, I am NOT suggesting you implement any caching in Ember Data.
All I am saying is, give me a hook where I can implement my own caching. I want to be able to decide when an XHR should fire off, and when not. That is exactly what I am doing with findAll/shouldReloadAll at this moment. (But I want to use query for another reason.)
Let me return true/false in that hook. Based on that result you proceed and make the promiseArray() call.
This is how shouldReloadAll is called: if (adapter.shouldReloadAll(this, snapshotArray)). And snapshotArray is a snapshot of this.peekAll(modelName). Couldn't something similar be available for query?
Do you understand what I mean?
If this.peekAll(modelName) does not make sense for query, then how about passing in no snapshot data at all, but simply the query params?
The goal is to prevent two requests to the server when:
this.store.query('article', { page: 1 }}
this.store.query('article', { page: 1 }}
are called subsequently.
I should be able to return false in the shouldReloadQuery if I detect page is the same (for example).
Most helpful comment
Hi @nicolas-dular. I marked this issue for for discussion at the next Ember Data weekly meeting.