Skip to content

Instantly share code, notes, and snippets.

@yann-yinn
Last active March 21, 2024 09:28
Show Gist options
  • Save yann-yinn/5a8c00866872251e22ef8acf94188a9f to your computer and use it in GitHub Desktop.
Save yann-yinn/5a8c00866872251e22ef8acf94188a9f to your computer and use it in GitHub Desktop.
Use "apollo-client" package with Vue.js, without "vue-apollo"
// Example on how to create your own apolloClient. Just import this file from any of
// your component to begin to launch your graphql queries, mutations etc and that's it.
// Nothing more is needed, apolloClient by itself is already very powerful, without using vue-apollo.
//
// @see https://www.apollographql.com/docs/react/basics/setup.html
// @see https://www.apollographql.com/docs/react/api/apollo-client.html
import { ApolloClient } from 'apollo-client';
import { createHttpLink } from 'apollo-link-http';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { setContext } from 'apollo-link-context';
import { getUser } from '@/app/lib/auth';
const httpLink = createHttpLink({
uri: process.env.VUE_APP_API_GRAPHQL_URL
});
const authLink = setContext((_, { headers }) => {
// get the authentication token from local storage if it exists
const user = getUser();
// return the headers to the context so httpLink can read them
return {
headers: {
...headers,
authorization: user.token ? `Bearer ${user.token}` : ''
}
};
});
const client = new ApolloClient({
link: authLink.concat(httpLink),
cache: new InMemoryCache()
});
export default client;
<!--
If you really like to use apolloClient declaratively, here is a naive implementation
of a custom 'ApolloQuery' component
-->
<template>
<div>
<slot name="result" :result="this.result" />
</div>
</template>
<script>
import apolloClient from '@/app/lib/apolloClient';
export default {
data() {
return {
// some default values until query begin
result: {
data: null,
loading: false,
networkStatus: 7,
error: null
}
};
},
props: {
query: {
type: Object,
required: true
},
variables: {
type: Object,
required: true
},
options: {
type: Object,
default: () => ({})
}
},
methods: {
// you can call this method from outside of the component, using "ref" attribute
// This is might be useful to relaunch the query after a mutation happened in the parent
apolloQuery(variables = {}, options = {}) {
this.result.loading = true;
return apolloClient
.query({
...this.options,
...options,
query: this.query,
variables: {
...this.variables,
...variables
}
})
.then(result => {
this.result = result;
})
.catch(error => {
this.result.error = error;
});
}
},
created() {
this.apolloQuery();
},
watch: {
variables: {
deep: true,
handler: function() {
this.apolloQuery();
}
}
}
};
</script>
<!--
This is an example on how to call declaratively
apolloClient with a custom ApolloQuery component
@see ApolloQuery.vue in this Gist
-->
<template>
<div>
<ApolloQuery :query="query" :variables="queryVariables">
<template #result="{ result: { data, loading, error } }">
<div v-if="loading">Loading</div>
<div v-if="error">{{ error }}</div>
<div v-if="data">{{ data }}</div>
</template>
</ApolloQuery>
</div>
</template>
<script>
import apolloClient from '@/app/lib/apolloClient';
// here is an example on how to call manually "apolloClient" from one of your component
export default {
data() {
return {
result: null,
error: null,
state: 'NOT_STARTED'
}
},
created() {
this.state = 'PENDING'; // state to use to display a loading message
apolloClient
.query({
query: yourQuery,
variables: {
id
}
})
.then(result => {
this.result = result;
this.state = 'FINISHED_OK';
})
.catch(error => {
this.error = error;
this.state = 'FINISHED_ERROR'
});
}
}
}
</script>
@ebisbe
Copy link

ebisbe commented Mar 29, 2019

I will try this today and see if it works for my use cases.

@davyzhang
Copy link

Thank you so much, this is exactly what I want. Make life a lot easier with less magic tricks

@yann-yinn
Copy link
Author

@davyzhang glad it helped.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment