Querying data
The Query
type in your GraphQL schema contains each query that you can dispatch. mobx-depot
converts each query
into its own class.
For example, given the following schema:
type Query { user(id: ID!): User}
This will generate a UserQuery
class that you can use as such:
import { UserQuery } from "~/models/depot";const userQuery = new UserQuery( // Query variables { id: 1 }, // Select the fields you want to retrieve user => user.name.email, // Optionally provide any applicable options, currently there's only a "cachePolicy" property: { // By default, the query will use the value you provided when calling initializeDepotClient // (which defaults to "cache-and-network") cachePolicy: "network-only" });userQuery.dispatch().then(user => { // user is a UserModel, which is a MobX observable // It can also be null, as described by the schema});
If you want to re-use the same query instance, you can provide a new set of variables
when calling dispatch
:
userQuery.dispatch({ id: 2 })// ...userQuery.dispatch({ id: 3 })// ...userQuery.dispatch({ id: 4 })
Sometimes when instantiating a query you may not know what variables it will use. In this case you can provide null
in the constructor:
const userQuery = new UserQuery( // We don't know the query arguments yet! null, user => user.name.email,);// ... We did some stuff, and now we know what ID we want:userQuery.dispatch({ id: 1 })
If you call dispatch
without ever providing variables, it will throw an error at runtime.
Query builder
When constructing queries and mutations with mobx-depot
, in order to select which fields to retrieve you need to
provide a function that returns the fields you want to retrieve. Type annotations are provided for your convenience.
import { UserQuery } from "~/models/depot";const userQuery = new UserQuery( { id: 1 }, user => user.name.email.createdAt.updatedAt);
This function will generate the following document:
query UserQuery($id: ID!) { user(id: $id) { name email createdAt updatedAt }}
However this can be shortened by using the primitives
key, instead of listing all the fields:
const userQuery = new UserQuery( { id: 1 }, user => user.primitives);
This will generate the same document.
Nested objects
Given the following schema:
type User { name: String email: String address: Address}type Address { street: String city: String country: String}
The query builder provides functions to select fields within nested objects:
const userQuery = new UserQuery( { id: 1 }, user => user.name.address(address => address.street.city.country).email);
This will generate the following document:
query UserQuery($id: ID!) { user(id: $id) { name email address { street city country } }}
Again, this can be shortened by using the primitives
key:
const userQuery = new UserQuery( { id: 1 }, user => user.primitives.address(address => address.primitives));
Nested field arguments
Given the following schema:
type Post { id: ID! title: String content: String}type User { name: String email: String posts(limit: Int!, offset: Int): [Post]}
You can provide an object containing arguments for the posts
field:
const userQuery = new UserQuery( { id: 1 }, user => user.name.email.posts({ limit: 10, offset: 0 }, post => post.title.content));
This will generate the following document:
query UserQuery($id: ID!) { user(id: $id) { name email posts(limit: 10, offset: 0) { title content } }}
Note: Since the
limit
argument in this case is non-nullable, TypeScript will enforce that you provide a value for it.