diff --git a/packages/docs/src/guide-composable/query.md b/packages/docs/src/guide-composable/query.md index 91e3360..e4c726b 100644 --- a/packages/docs/src/guide-composable/query.md +++ b/packages/docs/src/guide-composable/query.md @@ -231,6 +231,45 @@ Beware that `result` may not contain your data at all time! It will initially be ``` +We can use a `computed` prop to simplify access to part of the result and to provide a default value: + +```vue{2,19,22,30} + + + +``` + ## Query status ### Loading state @@ -318,210 +357,6 @@ export default { ``` -## useResult - -The sister composition function `useResult` is available alongside `useQuery` to facilitate usage of the query `result`. - -### Result picking - -The first useful feature of `useResult` is picking one object from the result data. To do so, pass the `result` data as the first parameter, and a picking function as the third parameter: - -```vue{2,18,21,34,35} - - - -``` - -This is very useful if the data relevant to your component is nested in the query: - -```js -const { result } = useQuery(gql` - query getMessages { - currentUser { - messages { - id - text - } - } - } -`) - -const messages = useResult(result, null, data => data.currentUser.messages) -``` - -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! -const messages = useResult(result, null, data => data && data.currentUser && data.currentUser.messages) - -// Instead do this: -const messages = useResult(result, null, data => data.currentUser.messages) -``` - -::: tip -Don't forget that `messages.value` can still be `null` until the query successfully completes! -::: - -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` - query getUsersAndPosts { - users { - id - email - } - - posts { - id - title - } - } -`) - -const users = useResult(result, null, data => data.users) - -const posts = useResult(result, null, data => data.posts) -``` - -Look how we cleanly separated the result data into two different `Ref`! - -### Automatic picking - -If there is only one object in the data, `useResult` will automatically try to pick the object: - -```js{12} -const { result, loading } = useQuery(gql` - query getUsers { - users { - id - firstname - lastname - email - } - } -`) - -const users = useResult(result) -``` - -Here `users.value` will be the `users` array retrieved from our server. - -### Default value - -Let's say we want to sort our users on their last names: - -```vue{2,19-21,24,34,35} - - - -``` - -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: - -```js -const sortedUsers = computed(() => result.value && result.value.users ? result.value.users.sort( - (a, b) => a.lastname.localeCompare(b.lastname) -) : []) -``` - -We can further simplify this with `useResult`: - -```js{1,3,5} -const users = useResult(result) // Automatically picked - -const sortedUsers = computed(() => users.value ? users.value.sort( - (a, b) => a.lastname.localeCompare(b.lastname) -) : []) -``` - -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 - -const sortedUsers = computed(() => users.value.sort( - (a, b) => a.lastname.localeCompare(b.lastname) -)) -``` - -This is even more useful if we want to use the `users` array `Ref` in multiple places in our `setup` function! - ## Variables You can pass a `variables` object to the 2nd parameter of `useQuery`: diff --git a/packages/vue-apollo-composable/src/useResult.ts b/packages/vue-apollo-composable/src/useResult.ts index be8661a..c153a81 100644 --- a/packages/vue-apollo-composable/src/useResult.ts +++ b/packages/vue-apollo-composable/src/useResult.ts @@ -16,6 +16,7 @@ export type UseResultReturn = Readonly>> * * @param {Ref} result A `result` returned from `useQuery` to resolve. * @returns Readonly ref with `undefined` or the resolved `result`. + * @deprecated Use `computed` instead. Before: `const items = useResult(result, [], data => data.someField.myItems)` After: `const items = computed(() => result.value?.someField.myItems ?? [])` */ export function useResult = keyof NonNullable> ( result: Ref @@ -34,6 +35,7 @@ export function useResult * @param {Ref} result A `result` returned from `useQuery` to resolve. * @param {TDefaultValue} defaultValue The default return value before `result` is resolved. * @returns Readonly ref with the `defaultValue` or the resolved `result`. + * @deprecated Use `computed` instead. Before: `const items = useResult(result, [], data => data.someField.myItems)` After: `const items = computed(() => result.value?.someField.myItems ?? [])` */ export function useResult = keyof NonNullable> ( result: Ref, @@ -53,6 +55,7 @@ export function useResultTReturnValue} pick The function that receives `result` and maps a return value from it. * @returns Readonly ref with the `defaultValue` or the resolved and `pick`-mapped `result` + * @deprecated Use `computed` instead. Before: `const items = useResult(result, [], data => data.someField.myItems)` After: `const items = computed(() => result.value?.someField.myItems ?? [])` */ export function useResult< TResult, @@ -64,6 +67,9 @@ export function useResult< pick: (data: DeepRequired>) => TReturnValue ): UseResultReturn +/** + * @deprecated Use `computed` instead. Before: `const items = useResult(result, [], data => data.someField.myItems)` After: `const items = computed(() => result.value?.someField.myItems ?? [])` + */ export function useResult< TResult, TDefaultValue, @@ -73,6 +79,11 @@ export function useResult< defaultValue?: TDefaultValue, pick?: (data: DeepRequired>) => TReturnValue, ): UseResultReturn { + console.warn(`'useResult' is deprecated and will be removed soon. Plase use a computed instead. +Before: +const items = useResult(result, [], data => data.someField.myItems) +After: +const items = computed(() => result.value?.someField.myItems ?? [])`) return computed(() => { const value = result.value if (value) {