Reactive Query
Each query declared in the apollo
definition (that is, which doesn't start with a $
char) in a component results in the creation of a reactive query object.
Options
query
: GraphQL document (can be a file or agql
string).variables
: Object or reactive function that returns an object. Each key will be mapped with a'$'
in the GraphQL document, for examplefoo
will become$foo
.throttle
: throttle variables updates (in ms).debounce
: debounce variables updates (in ms).pollInterval
: auto update using polling (which means refetching everyx
ms). Default:undefined
,0
- stop polling. Alternatively this may be a reactive function that returns the polling interval. Returnnull
to stop the polling.update(data) {return ...}
to customize the value that is set in the vue property, for example if the field names don't match.result(ApolloQueryResult, key)
is a hook called when a result is received (see documentation for ApolloQueryResult).key
is the query key in theapollo
option.error(error, vm, key, type, options)
is a hook called when there are errors.error
is an Apollo error object with either agraphQLErrors
property or anetworkError
property.vm
is the related component instance.key
is the reactive query key.type
is either'query'
or'subscription'
.options
is the finalwatchQuery
options object.loadingKey
will update the component data property you pass as the value. You should initialize this property to0
in the componentdata()
hook. When the query is loading, this property will be incremented by 1; when it is no longer loading, it will be decremented by 1. That way, the property can represent a counter of currently loading queries.watchLoading(isLoading, countModifier)
is a hook called when the loading state of the query changes. ThecountModifier
parameter is either equal to1
when the query is loading, or-1
when the query is no longer loading.manual
is a boolean to disable the automatic property update. If you use it, you then need to specify aresult
callback (see example below).deep
is a boolean to usedeep: true
on Vue watchers.skip
is a boolean or a (reactive) function that returns a boolean. The function gets the current component and reactive query key as arguments, so it can be used in$query
and inApolloProvider
'sdefaultOptions
.subscribeToMore
: an object or an array of object which are subscribeToMore options.prefetch
is either a boolean or a function to determine if the query should be prefetched. See Server-Side Rendering.- You can also use any other
watchQuery
options (see Apollo docs).
Example:
js
// Apollo-specific options
apollo: {
// Advanced query with parameters
// The 'variables' method is watched by vue
pingMessage: {
query: gql`query PingMessage($message: String!) {
ping(message: $message)
}`,
// Reactive parameters
variables () {
// Use vue reactive properties here
return {
message: this.pingInput,
}
},
// Polling interval in milliseconds
pollInterval: 10000,
// Or, set polling interval as a vue reactive property
pollInterval() {
return this.pollInterval;
},
// Variables: deep object watch
deep: false,
// We use a custom update callback because
// the field names don't match
// By default, the 'pingMessage' attribute
// would be used on the 'data' result object
// Here we know the result is in the 'ping' attribute
// considering the way the apollo server works
update (data) {
console.log(data)
// The returned value will update
// the vue property 'pingMessage'
return data.ping
},
// Optional result hook
result ({ data, loading, networkStatus }) {
console.log('We got some result!')
},
// Error handling
error (error) {
console.error('We\'ve got an error!', error)
},
// Loading state
// loadingKey is the name of the data property
// that will be incremented when the query is loading
// and decremented when it no longer is.
loadingKey: 'loadingQueriesCount',
// watchLoading will be called whenever the loading state changes
watchLoading (isLoading, countModifier) {
// isLoading is a boolean
// countModifier is either 1 or -1
},
},
},
If you use ES2015
, you can also write the update
like this:
js
update: data => data.ping
Manual mode example:
js
{
query: gql`...`,
manual: true,
result ({ data, loading }) {
if (!loading) {
this.items = data.items
}
},
}
Properties
skip
You can pause or unpause with skip
:
js
this.$apollo.queries.users.skip = true
loading
Whether the query is loading:
js
this.$apollo.queries.users.loading
Methods
refresh
Stops and restarts the query:
js
this.$apollo.queries.users.refresh()
start
Starts the query:
js
this.$apollo.queries.users.start()
stop
Stops the query:
js
this.$apollo.queries.users.stop()
fetchMore
Load more data for pagination:
js
this.page++
this.$apollo.queries.tagsPage.fetchMore({
// New variables
variables: {
page: this.page,
pageSize,
},
// Transform the previous result with new data
updateQuery: (previousResult, { fetchMoreResult }) => {
const newTags = fetchMoreResult.tagsPage.tags
const hasMore = fetchMoreResult.tagsPage.hasMore
this.showMoreEnabled = hasMore
return {
tagsPage: {
__typename: previousResult.tagsPage.__typename,
// Merging the tag list
tags: [...previousResult.tagsPage.tags, ...newTags],
hasMore,
},
}
},
})
subscribeToMore
Subscribe to more data using GraphQL subscriptions:
js
// We need to unsubscribe before re-subscribing
if (this.tagsSub) {
this.tagsSub.unsubscribe()
}
// Subscribe on the query
this.tagsSub = this.$apollo.queries.tags.subscribeToMore({
document: TAG_ADDED,
variables: {
type,
},
// Mutate the previous result
updateQuery: (previousResult, { subscriptionData }) => {
// If we added the tag already don't do anything
// This can be caused by the `updateQuery` of our addTag mutation
if (previousResult.tags.find(tag => tag.id === subscriptionData.data.tagAdded.id)) {
return previousResult
}
return {
tags: [
...previousResult.tags,
// Add the new tag
subscriptionData.data.tagAdded,
],
}
},
})
refetch
Fetch the query again, optionally with new variables:
js
this.$apollo.queries.users.refetch()
// With new variables
this.$apollo.queries.users.refetch({
friendsOf: 'id-user'
})
setVariables
Update the variables on the query and refetch it if they have changed. To force a refetch, use refetch
.
js
this.$apollo.queries.users.setVariables({
friendsOf: 'id-user'
})
setOptions
Update the Apollo watchQuery options and refetch:
js
this.$apollo.queries.users.setOptions({
fetchPolicy: 'cache-and-network'
})
startPolling
Start an auto update using polling (which means refetching every x
ms):
js
this.$apollo.queries.users.startPolling(2000) // ms
stopPolling
Stop the polling:
js
this.$apollo.queries.users.stopPolling()