docs: fixes and improvements

This commit is contained in:
Guillaume Chau
2019-12-01 15:49:12 +01:00
parent 9ac2783229
commit e49931309c
4 changed files with 91 additions and 25 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
# Introduction
The Composition API is an API allowing writing data and logic in an easily composable way inside the `setup` option.
The Composition API is an API where you write data and logic in an easily composable way inside the `setup` option.
If you are using Typescript, it is strongly recommended to start using the Composition API as its typing capabilities are unmatched by any other Vue API.
@@ -4,7 +4,7 @@ Now that's we've learned [how to fetch data](./query), the next logical step is
## Executing a mutation
The `useMutation` composition function is the main way of setting up mutation in Vue components.
The `useMutation` composition function is the main way of setting up mutations in Vue components.
Start by importing it in your component:
+86 -22
View File
@@ -1,10 +1,12 @@
# Queries
Fetching data involves executing **queries** using standard GraphQL documents. You can learn more about queries and GraphQL documents [here](https://graphql.org/learn/queries/) and [practice running queries in the playground](https://www.apollographql.com/docs/react/development-testing/developer-tooling/#features).
Fetching data involves executing **query** operations using standard GraphQL documents. You can learn more about queries and GraphQL documents [here](https://graphql.org/learn/queries/) and [practice running queries in the playground](https://www.apollographql.com/docs/react/development-testing/developer-tooling/#features).
## Executing a query
Let's take this GraphQL document to execute our query:
### GraphQL document
Let's take this example GraphQL document throughout this section:
```graphql
query getUsers {
@@ -18,9 +20,71 @@ query getUsers {
```
::: tip
It's recommended to give a name to your GraphQL operations (here `getUsers`), so it's easier to find them in the Apollo Client devtools.
It is recommended to give a name to your GraphQL operations (here `getUsers`), so it is easier to find them in the Apollo Client devtools.
:::
This query would return a `data` object with an array of `users` with their `id`, `firstname`, `lastname` and `email`. It could look like this:
```json
{
"data": {
"users": [
{
"id": "abc",
"firstname": "James",
"lastname": "Holden",
"email": "james.holden@roci.com"
},
{
"id": "def",
"firstname": "Naomi",
"lastname": "Nagata",
"email": "naomi.nagata@roci.com"
}
]
}
}
```
You may ask: why is there a nested `users` property on `data`? Why isn't the array directly on `data`?
This is because you can select multiple root fields in a GraphQL operation:
```graphql
query getCatsAndDogs {
cats {
id
}
dogs {
id
}
}
```
In this case, the result could look like this:
```json
{
"data": {
"cats": [
{ "id": "abc" },
{ "id": "def" }
],
"dogs": [
{ "id": "ghi" },
{ "id": "jkl" }
]
}
}
```
There can also be other optional properties on the result alongside `data`:
- `errors` : an array of errors returned by the server
- `extensions` : additional informations such as execution timings
### useQuery
The main composition function used to execute queries is `useQuery`. In your component, start by importing it:
```vue
@@ -35,7 +99,7 @@ export default {
</script>
```
You can use `useQuery` in your `setup` option by passing it a GraphQL document as the first parameter and retrieve the query `result`:
You can use `useQuery` in your `setup` option and pass it a GraphQL document as the first parameter. Then retrieve the query `result`:
```vue{3,7-16}
<script>
@@ -59,7 +123,7 @@ export default {
</script>
```
Note that `result` here is a `Ref` holding the data from the result object retrieved from Apollo.
Note that `result` here is a `Ref` holding the data from the result returned by Apollo.
If you want to directly access the data object, use `result.value`:
@@ -90,7 +154,7 @@ export default {
</script>
```
In this case, you can also watch the `Ref` directly:
In this example, you could also watch the `Ref` directly:
```vue{19-20}
<script>
@@ -155,7 +219,7 @@ export default {
</template>
```
Beware that `result` may not contain your data! At the beginning, it will be `undefined` until the query successfully completes. So it's a good idea to add a conditionnal before rendering the fetched data:
Beware that `result` may not contain your data at all time! It will initially be `undefined` until the query successfully completes. So it's a good idea to add a conditionnal before rendering the data:
```vue{2}
<template>
@@ -171,7 +235,7 @@ Beware that `result` may not contain your data! At the beginning, it will be `un
### Loading state
Alongside `result`, `useQuery` returns `loading` which is a boolean `Ref`, so you can track the loading state of the query:
Alongside `result`, `useQuery` returns `loading`, a boolean `Ref` tracking the loading state of the query:
```vue{7,20,27,29}
<script>
@@ -212,7 +276,7 @@ export default {
### Error
There is also an `error` `Ref` that stores any error that may occur:
There is also an `error` `Ref` that holds any error that may occur during the request:
```vue{7,21,30}
<script>
@@ -256,7 +320,7 @@ export default {
## useResult
A sister composition function `useResult` is available alongside `userQuery` to facilitate usage of the query `result`.
The sister composition function `useResult` is available alongside `userQuery` to facilitate usage of the query `result`.
### Result picking
@@ -321,7 +385,7 @@ const { result } = useQuery(gql`
const messages = useResult(result, null, data => data.currentUser.messages)
```
Another perk of `useResult` is that the picking function will silently throw an error if `result.value` is `undefined`, so you don't have to add additional checks:
Another perk of `useResult` is that the picking function will silence errors inside the picking function. For example, if `result.value` is `undefined`, you don't have to add additional checks:
```js
// You don't need to do this!
@@ -335,7 +399,7 @@ const messages = useResult(result, null, data => data.currentUser.messages)
Don't forget that `messages.value` can still be `null` until the query successfully completes!
:::
Another use case where `useResult` is very useful is when you have multiple objects on the result data:
Another use case where `useResult` proves to be very useful is when you have multiple objects on the result data:
```js
const { result } = useQuery(gql`
@@ -382,7 +446,7 @@ Here `users.value` will be the `users` array retrieved from our server.
### Default value
Let's say we want to sort our user on last names:
Let's say we want to sort our users on their last names:
```vue{2,19-21,24,34,35}
<script>
@@ -426,9 +490,9 @@ export default {
</template>
```
Here we will run into an error because `result.value` can be `undefined` (and potentially `result.value.users` can also be `undefined`). So `sort()` will throw when called in our computed property.
Here we will run into an error because `result.value` can be `undefined` (and potentially `result.value.users` can also be `undefined`). So the `sort` method will throw an error when called in our `computed` property.
We could add checks but it can rapidly become tedious:
We could add checks, but it can rapidly become tedious:
```js
const sortedUsers = computed(() => result.value && result.value.users ? result.value.users.sort(
@@ -446,7 +510,7 @@ const sortedUsers = computed(() => users.value ? users.value.sort(
) : [])
```
But we can eliminate the conditional completly if we pass a default value as the 2nd parameter of `useResult`:
But we can eliminate the conditional entirely if we pass a default value as the 2nd parameter of `useResult`:
```js{1,3,5}
const users = useResult(result, []) // Defaults to an empty array
@@ -456,7 +520,7 @@ const sortedUsers = computed(() => users.value.sort(
))
```
This is even more useful if we want to use this `users` array `Ref` in multiple places in our `setup` function!
This is even more useful if we want to use the `users` array `Ref` in multiple places in our `setup` function!
## Variables
@@ -552,7 +616,7 @@ function selectUser (id) {
}
```
This also means you can pass `props` from `setup` directly, since `props` is a reactive object:
This also means you can pass `props` from `setup` directly, since `props` is already a reactive object:
```js
export default {
@@ -575,7 +639,7 @@ export default {
}
```
But beware if you add new props that aren't in the GraphQL query, you may run into GraphQL validation errors!
But beware if you add new props that aren't used in the GraphQL document, you will run into GraphQL validation errors!
### Variables function
@@ -706,7 +770,7 @@ function enableQuery () {
### Fetch Policy
The `fetchPolicy` option allow you to customize how the query will use the Apollo Client cache.
The `fetchPolicy` option allows you to customize how the query will use the Apollo Client cache.
```js
const { result } = useQuery(gql`
@@ -726,7 +790,7 @@ Available values are:
## Updating cached results
When a query is completed, it will update the cache with the result data (depending on the [fetch policy](#fetch-policy)). This optimize the next time the data needs to be rendered in your application and ensures that all components relying on a piece of data is always consistent.
When a query is completed, it will update the cache with the result data (depending on the [fetch policy](#fetch-policy)). This improves performance the next time the data needs to be rendered in your application and ensures that all components relying on a piece of data is always consistent.
However, you sometimes want to make sure that this data is up-to-date compared to the server.
@@ -734,7 +798,7 @@ However, you sometimes want to make sure that this data is up-to-date compared t
Polling means repeatedly calling the server to automatically update the query data.
You can enable polling with the `pollInterval` which will be the interval in ms between each requests repeatdly made to the server.
You can enable polling with the `pollInterval` which will be the interval in ms between each requests repeatedly made to the server.
In this example, we will poll the server every second:
+3 -1
View File
@@ -50,7 +50,7 @@ const app = new Vue({
})
```
You can add other client instances alongside:
You can add other client instances alongside it:
```js
provide(ApolloClients, {
@@ -59,3 +59,5 @@ provide(ApolloClients, {
clientB: apolloClientB,
})
```
You can then select which one to use in functions we will cover next (such as `useQuery`, `useMutation` and `useSubscription`) with the `clientId` option.