Hi everyone,
Here is my setup of apollo client
const httpLink = new HttpLink({ uri: 'https://api.graph.cool/simple/v1/cjaeub9io2kcz0115e4m0ql6d' })
let token = localStorage.getItem('GC_AUTH_TOKEN')
const middlewareLink = new ApolloLink((operation, forward) => {
operation.setContext({
headers: { authorization: `Bearer ${token}` }
})
return forward(operation)
})
const link = middlewareLink.concat(httpLink)
const apolloClient = new ApolloClient({
link,
cache: new InMemoryCache()
})
after login, I mean after we set localStorage token, we have to reload the web app to apply middleware to apollo client. Is there any solution for this?
Why don't you update your token variable?
token = localStorage.getItem('GC_AUTH_TOKEN')
@Akryum
Thanks for reply. I put it in main.js
import Vue from 'vue'
import axios from 'axios'
import App from './App'
import router from './router'
import store from './store'
// Plugin
import Acl from './plugins/vue-acl'
import Buefy from 'buefy'
import 'mdi/css/materialdesignicons'
// Vue Apollo
import { ApolloClient } from 'apollo-client'
import { ApolloLink } from 'apollo-link'
import { HttpLink } from 'apollo-link-http'
import { InMemoryCache } from 'apollo-cache-inmemory'
import VueApollo from 'vue-apollo'
// Vue Electron
if (!process.env.IS_WEB) Vue.use(require('vue-electron'))
Vue.http = Vue.prototype.$http = axios
Vue.config.productionTip = false
// Vue Apollo
const httpLink = new HttpLink({ uri: 'https://api.graph.cool/simple/v1/cjaeub9io2kcz0115e4m0ql6d' })
let token = localStorage.getItem('GC_AUTH_TOKEN')
const middlewareLink = new ApolloLink((operation, forward) => {
operation.setContext({
headers: { authorization: `Bearer ${token}` }
})
return forward(operation)
})
const link = middlewareLink.concat(httpLink)
const apolloClient = new ApolloClient({
link,
cache: new InMemoryCache()
})
// Install Plugin
Vue.use(VueApollo)
Vue.use(Buefy)
Vue.use(Acl, {
router,
init: 'public',
fail: '/login'
})
const apolloProvider = new VueApollo({
defaultClient: apolloClient
})
/* eslint-disable no-new */
new Vue({
components: { App },
router,
store,
apolloProvider,
template: '<App/>'
}).$mount('#app')
I don't know how to update token variable from a component. Can you guide me how to do it.
Object.defineProperty(Vue.prototype, '$token', {
get () { return token },
set (value) { token = value },
})
this.$token = 'new-value'
Thanks for your help.
@kieusonlam Did you solve the issue? If then, can you post the working code snippet here? Thanks.
The solution worked. Just had mistake on my side. Thank you.
Fyi, here is my code snippet using apollo-boost.
// main.ts
import Vue from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';
import VueApollo from 'vue-apollo';
import ApolloClient from 'apollo-boost';
Vue.use(VueApollo);
Vue.config.productionTip = false;
let token = localStorage.getItem('token');
Object.defineProperty(Vue.prototype, '$token', {
get() { return token },
set(value) { token = value },
})
const uri = 'your-graphql-uri'
const client = new ApolloClient({
uri,
request: (operation) => {
operation.setContext({
headers: {
Authorization: token ? `Bearer ${token}` : ''
}
});
}
});
const apolloProvider = new VueApollo({
defaultClient: client
});
new Vue({
router,
store,
render: (h) => h(App),
apolloProvider
}).$mount('#app');
In the login component after you get the token from server just add this line.
this.$token = 'some_token';
I'm having the same issue using ApolloClient. I have to refresh the page to make the ApolloClient knowing the token.
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import { ApolloClient } from 'apollo-client';
import { HttpLink } from 'apollo-link-http';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { CA_USER_TOKEN, CA_USER_TYPE } from '../utils/settings';
const token = localStorage.getItem(CA_USER_TOKEN)
const userType = localStorage.getItem(CA_USER_TYPE)
export const apolloClient = new ApolloClient({
link: new HttpLink({
uri: 'http://localhost:81/api',
headers: {
Authorization: Bearer + localStorage.getItem(CA_USER_TOKEN),
UserType: localStorage.getItem(CA_USER_TYPE),
},
}),
cache: new InMemoryCache(),
connectToDevTools: true,
})
const apolloProvider = new VueApollo({
defaultClient: apolloClient,
})
Vue.use(VueApollo)
export default apolloProvider
How can I solve this?
@samuelhgf You set your headers only once.
@Akryum I didn't understand want you mean. Can tou explain what should I do, pleae?
Your object containing the headers is only created once, hence why you need to reload the page to apply new values from the local storage. See example solutions above in the thread or read the documentation.
But I will need to use the setContext, right?
My code:
`import Vue from 'vue';
import VueApollo from 'vue-apollo';
import { ApolloClient } from 'apollo-client';
import { createHttpLink } from 'apollo-link-http';
import { setContext } from 'apollo-link-context';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { CA_USER_TOKEN, CA_USER_TYPE } from '../utils/settings';
const httpLink = createHttpLink({
uri: 'http://localhost:81',
});
const authLink = setContext((_, { headers }) => {
// get the authentication token from local storage if it exists
const token = localStorage.getItem(CA_USER_TOKEN);
const userType = localStorage.getItem(CA_USER_TYPE);
// return the headers to the context so httpLink can read them
return {
headers: {
...headers,
authorization: token ? Bearer ${token} : "",
UserType: userType,
}
}
});
export const apolloClient = new ApolloClient({
link: authLink.concat(httpLink),
cache: new InMemoryCache(),
connectToDevTools: true,
});
const apolloProvider = new VueApollo({
defaultClient: apolloClient,
})
Vue.use(ApolloClient)
export default apolloProvider`
But I'm getting this error: Uncaught TypeError: Cannot set property 'defaultOptions' of null
Most helpful comment