apollographql / apollo-client

:rocket:  A fully-featured, production ready caching GraphQL client for every UI framework and GraphQL server.
https://apollographql.com/client
MIT License
19.38k stars 2.66k forks source link

Vue Apollo not resetting store on logout! #3490

Closed romucci closed 6 years ago

romucci commented 6 years ago

Hi there guys! I am using apollo client for my vue app, but for example this happens:

1 - I login with an account. 2 - Navigate inside a component via vue-router. 3 - A query for a product list gets triggered. 4 - I logout. 5 - I login inside another account. (The queries are fetched by current User ID) 6 - I navigate to the same component via vue-router. 7 - I see the information from the other account for a split second and then the information from the current user appears.

I tried client.resetStore() and client.cache.clear() or client.cache.data.clear().

methods: {
    logout () {
      Object.values(this.$apollo.provider.clients)
        .forEach(client => client.cache.data.clear())
      sessionStorage.clear()
      localStorage.clear()
      this.$store.state.user = null
      this.$store.state.token = null
      this.$store.state.isUserLoggedIn = false
      this.$router.push('/login')
    }
  }

Nothing worked. :)

romucci commented 6 years ago

Fixed it :)

m4tty-d commented 6 years ago

@romucci Can you share what was the solution? :)

techyrajeev commented 5 years ago

Fixed it :)

Please share

RoelRoel commented 5 years ago

What is the solution?

Musbell commented 5 years ago

@romucci pls share

stephpasquini commented 5 years ago

This is the solution that I found for a vue app with vue-apollo and vuex

First create the apolloClient inside a file like apollo/index.js

import { ApolloClient } from "apollo-client";
import { HttpLink } from "apollo-link-http";
import { setContext } from "apollo-link-context";
import { InMemoryCache } from "apollo-cache-inmemory";

const httpLink = new HttpLink({
  uri: process.env.VUE_APP_SERVER_ENDPOINT
});

const httpLinkAuth = setContext((_, { headers }) => {
  // get the authentication token from localstorage if it exists
  const token = localStorage.getItem("USER_TOKEN");

  // return the headers to the context so httpLink can read them
  return {
    headers: {
      ...headers,
      Authorization: token ? `Bearer ${token}` : ""
    }
  };
});

export const apolloClient = new ApolloClient({
  link: httpLinkAuth.concat(httpLink),
  cache: new InMemoryCache(),
  connectToDevTools: true
});

inside the main.js

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";

Vue.use(VueApollo);

Vue.config.productionTip = false;

const apolloProvider = new VueApollo({
  defaultClient: apolloClient
});

new Vue({
  router,
  store,
  apolloProvider,
  render: (h) => h(App)
}).$mount("#app");

In your vuex store

import { apolloClient } from "@/apollo";
const mutations = {
  setToken(state, token) {
    state.status = "success";
    state.token = token;
  },
  logout(state) {
    state.status = "";
    state.token = "";
  }
};
const actions = {
  logout(context) {
    localStorage.removeItem("USER_TOKEN");
    context.commit("logout");
    apolloClient.cache.data.clear();
  }
};