can-query-logic
Purpose
can-query-logic
is used to give CanJS an understanding of what the parameters used to
retrieve a list of data represent. This awareness helps other libraries like
[can-connect] and [can-fixture] provide real-time, caching and other behaviors.
The parameters used to retrieve a list of data?
In many applications, you request a list of data by making a fetch
or XMLHTTPRequest
to a url like:
/api/todos?filter[complete]=true&sort=name
The values after the ?
are used to control the data that comes back. Those values are
deserialized into
a query object look like this:
{
filter: {complete: true},
sort: "name"
}
This object represents a Query
. This specific query is for requesting completed todos and have the todos sorted by their name.
A QueryLogic
instance understands what a Query
represents. For example, it can filter records
that match a particular query:
var todos = [
{ id: 1, name: "learn CanJS", complete: true },
{ id: 2, name: "wash the car", complete: false },
{ id: 3, name: "do the dishes", complete: true }
]
var queryLogic = new QueryLogic();
var result = queryLogic.filterMembers({
filter: {complete: true}
}, todos);
result
The filterMembers
method allows QueryLogic
to be used similar to a database. QueryLogic
instances methods help solve other problems too:
- real-time -
.isMember
returns if a particular item
belongs to a query and .index
returns the location where that item belongs. - caching -
.isSubset
can tell you if you've already loaded
data you are looking for. .difference
can tell you what data
you need to load that already isn't in your cache.
In fact, can-query-logic
's most unique ability is to be able to directly compare
queries that represent sets of data instead of having to compare
the data itself. For example, if you already loaded all completed todos,
can-query-logic
can tell you how to get all remaining todos:
var completedTodosQuery = {filter: {complete: false}};
var allTodosQuery = {};
var remainingTodosQuery = queryLogic.difference(allTodosQuery, completedTodosQuery);
remainingTodosQuery
Matching the default query structure
By default, can-query-logic
assumes your service layer will match a default query structure
that looks like:
{
filter: {
complete: {$in: [false, null]}
},
sort: "-name",
page: {start: 0, end: 19}
}
This structures follows the Fetching Data JSONAPI specification.
There's:
- a filter property for filtering records,
- a sort property for specifying the order to sort records, and
- a page property that selects a range of the sorted result. The range indexes are inclusive.
If you control the service layer, we encourage you to make it match the default
query structure. The default query structure also supports the following comparison operators: $eq
, $gt
, $gte
, $in
, $lt
, $lte
, $ne
, $nin
.