apollo-state-link does not hold state in cache when page is refreshed - react-apollo

I noticed that when I update my cache locally on the clientside and it routes to another page, the cache persists with the data.
However, when I refresh that page, the cache is cleared. Is there a way to keep the cache state even after refreshing?

Apollo's InMemoryCache is, well, in-memory, so it's not persisted between page loads. The recommended way to persist your cache is to use apollo-cache-persist. Example usage:
import { InMemoryCache } from 'apollo-cache-inmemory'
import { persistCache } from 'apollo-cache-persist'
const cache = new InMemoryCache({...})
persistCache({
cache,
storage: window.localStorage,
});
const client = new ApolloClient({
cache,
// other client options
})
For advanced configuration and usage, check the repo. Also, be aware if you're using SSR, there are known issues with using this library. You could also checkout apollo-cache-instorage, which might be more SSR-friendly.

Related

Override browser cache in PWA service worker

I am using "caches" to cache in service worker my PWA assets and make it available offline.
When I change an asset, specifically a js file, I modify at least one byte in my service worker to trigger its native update: the service worker updates and retrieves all of its previously cached assets to refresh its caches.
Yet, server responds with a cached version of the file, and whereas I own the files served I have no control over Cache-Control http header.
How can i prevent browser caching on service worker cached resources? Versioning the files with a
"?v="+version
suffix won't work, because this version cannot be passed to the or or tags that references the cached files in html files, which are static and caches will not recognize and serve offline unversioned file names.
Since "caches.addAll" does not allow AFAIK any means to specify http request headers such as Cache-Control as fetch or XMLHttpRequest do, how can I prevent additional aggressive caching stages over my assets?
I am using plain Javascript and if possible I need it to be done without any additional library. Note also that meta http-equiv tags won't solve the problem for assets other than complete html.
You can bypass the browser's cache by explicitly constructing a Request object with a cache property set to an appropriate cache mode. 'reload' is a good choice, as it will bypass the browser's cache for the outgoing request, but it will update the browser's cache with the response (so you'll have a fresher browser cache overall). If you don't even want that update to be performed, you could use 'no-store'.
Here's some code showing how to do this concisely for an array of URLs that could be passed in to cache.addAll():
async function addAllBypassCache(cacheName, urls) {
const cache = await caches.open(cacheName);
const requests = urls.map((url) => new Request(url, {
cache: 'reload',
}));
await cache.addAll(requests);
}

Disable Cache Interceptor

Is there a possible way to disable Cache Interceptors while on development, except for putting minimum TTL for a cache?
#UseInterceptors(CacheInterceptor)
as a global, so the developer wont have to wait until the cache is cleared during development.
You can try this:
#UseInterceptors(process.env.NODE_ENV === "development" ? function() {} : CacheInterceptor)
Basically, use a dummy interceptor during development so that data won't be cached

Caching the axios httpService in NestJS

Within our application we use the Axios HttpService to do some request to a third-party api.
Because the amount of data returned bij de api is so huge, we would like to cache the responses.
In the docs is wasn't able to find some examples of how to do this.
I'm currently doing this as follows:
#Module({
imports: [
HttpModule,
CacheModule.register({
ttl: 15,
store: redisStore,
host: 'localhost',
port: 6379,
})
]
})
export class AppModule {}
I register the CacheModule globally.
Then import it in the module where i need it.
In the service where i use the third-party api, i create an interceptor where i go and cache the reponses. Very crude and just for testing.
constructor(private readonly httpService: HttpService,
private readonly cache: CacheStore) {
httpService.axiosRef.interceptors.response.use((response) => {
cache.set(response.request.url, response.data);
return response;
}, error => Promise.reject(error));
}
First of all this doesn't run, because the CACHE_MANAGER can't be imported into the CacheModule, for some reason.
Second this is a more a Node.js way of creating such interceptors and not the NestJS way.
But is this a way to move forward or is there a more effecient way and if yes, what way is that?
The CacheModule is not the right tool here, as it means to cache ingoing requests (the requests your service receive, so it doesn't proceed them again and send back a cache result).
What you're trying to do is caching the outgoing requests (the one your service makes to 3rd-party services). For mysterious reasons, I couldn't find it documented in NestJS documentation either, but here's how you can go:
As you're using Axios, you can implement caching using the axios-cache-adapter npm package.
npm install --save axios-cache-adapter
Then you need to create an adapter (preferably in the constructor of your service, see notes below):
const cache = setupCache({
maxAge: 3600 * 1000, // 60 minutes
});
and provide this adapter as part of the AxiosRequestConfig alongside your request:
const config = {
adapter: this.cache.adapter,
};
this.httpService.get( url, config );
You should be good with some caching now!
IMPORTANT NOTES:
caching should be used, and will likely work, only on GET requests
use the setupCache function only once (in the constructor of your service for instance); if you create one cache object for every request, this cache will be empty everytime, defeating the purpose of it

vuex store losing data on PAGE REGRESH

I am building authentication system in laravel and vuejs, I am building using JWT and storing token in lacalstorage. I am able to store user data in vuex store and yes i can see under vuex area in devtool. The problem is when i am refreshing page i am losing it . I wanna persist user's information, It should not get deleted on a page refresh . How can i achieve that
import Vue from 'vue'
import Vuex from 'vuex'
import userStore from './components/user/userStore'
Vue.use(Vuex)
const debug = process.env.NODE_ENV !== 'production'
export default new Vuex.Store({
modules : {
userStore
},
strict : debug
})
You can try using this plugin
https://github.com/championswimmer/vuex-persist
A Typescript-ready Vuex plugin that enables you to save the state of your app to a persisted storage like Cookies or localStorage.
You can try to save your Vuex to localstorage or cookie.
There is a plugin to help save your state to localstorage https://github.com/robinvdvleuten/vuex-persistedstate
I had exactly the same problem. I solved it that way:
state: {
authenticated: localStorage.getItem('yourToken')
}
Now you can set your this.authenticated in actions: {} or wherever else to true or false.
The meaning is that you have to store your localStrage by default to your i.e. autenticated.
If you cant follow, just let me know and I could give you more example of my case. Maybe you'll figured it out that way.
EDIT:
Use sessionStorage to store.

How to force update when using superagent cache?

I am using superagent-cache and superagent.
For most of my requests, I use this:
import superagentCache from 'superagent';
const superagent = superagentCache();
superagent is using the cache as expected.
For some request, I want to use the superagent and not the cache.
import superagent from "superagent";
But for even those requests, superagent continues to use the cached response. Any idea why this is happening?
superagent-cache patches the existing superagent. So, it is not possible to have the original superagent.
To avoid caching or force AJAX requests, use the forceUpdate param on the superagent-cache.

Resources