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 agqlstring).variables: Object or reactive function that returns an object. Each key will be mapped with a'$'in the GraphQL document, for examplefoowill become$foo.throttle: throttle variables updates (in ms).debounce: debounce variables updates (in ms).pollInterval: auto update using polling (which means refetching everyxms). Default:undefined,0- stop polling. Alternatively this may be a reactive function that returns the polling interval. Returnnullto 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).keyis the query key in theapollooption.error(error, vm, key, type, options)is a hook called when there are errors.erroris an Apollo error object with either agraphQLErrorsproperty or anetworkErrorproperty.vmis the related component instance.keyis the reactive query key.typeis either'query'or'subscription'.optionsis the finalwatchQueryoptions object.loadingKeywill update the component data property you pass as the value. You should initialize this property to0in 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. ThecountModifierparameter is either equal to1when the query is loading, or-1when the query is no longer loading.manualis a boolean to disable the automatic property update. If you use it, you then need to specify aresultcallback (see example below).deepis a boolean to usedeep: trueon Vue watchers.skipis 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$queryand inApolloProvider'sdefaultOptions.subscribeToMore: an object or an array of object which are subscribeToMore options.prefetchis either a boolean or a function to determine if the query should be prefetched. See Server-Side Rendering.- You can also use any other
watchQueryoptions (see Apollo docs).
Example:
js
export default {
// 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.pingManual mode example:
js
export default {
apollo: {
myQuery: {
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 = trueloading
Whether the query is loading:
js
this.$apollo.queries.users.loadingMethods
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) // msstopPolling
Stop the polling:
js
this.$apollo.queries.users.stopPolling()