Routes
With redux and redux-query, we still rely on the route to initiate our data-fetching, relying on many of the same route lifecycle methods you're already used to, namely, model and setupController.
model()
In vishnu-frontend, we rely extensively on Ember's documented behavior for the model method in a route:
Typically, the
modelhook should return an Ember Data record, but it can also return any promise object (Ember Data records are promises), or a plain JavaScript object or array. Ember will wait until the data finishes loading (until the promise is resolved) before rendering the template.
This is convenient, because it means we can block on any data fetching operation on a promise resolution, regardless of the underlying technology. It just needs to return a promise.
redux-query offers a function called dispatchAsync. This function takes a single object as an argument. This argument provides redux-query with instructions for fetching your data. It's required parameters are a url property and an update property. The url property tells redux-query where to fetch your data, and update tells redux-query how to merge it with any entities that may or may not be in the Redux store currently. Most importantly for us, dispatchAsync returns a promise that resolves when your data has been fetched. Thus, your route's model() hook might look like the following:
model(params) {
return this.actions.fetchUnitWithStudentAssignments(params.unit_id);
}
Where does that fetchUnitWithStudentAssignments action come from? We've imported it from a query creator file that we've also written, which, in this case, is located at vishnu/sagas/unit-details/queries.js. It looks something like this:
const fetchUnitWithStudentAssignments = (id, config = {}) => requestAsync({
url: queryFor('units').filter('id').is(id).include('student_assignments.').perPage(1024),
update: _.merge
});
This function creates an object that redux-query knows how to interpret as a request for data. The update property instructs redux to merge the returned data with lodash's (deep) merge function. There are many configuration options that you may pass in, if you so desire. Refer to the redux-query documentation for more up-to-date information this configuration object.
You may also be wondering what queryFor does. Its a simple URL building utility that shares some similarities with our query-expressions library. It does a lot less, but we don't need it to do very much. Here's more information about query-builder.