Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update GET cache after POST request. #344

Closed
arthurfiorette opened this issue Sep 8, 2022 · 3 comments
Closed

Update GET cache after POST request. #344

arthurfiorette opened this issue Sep 8, 2022 · 3 comments
Assignees
Labels
question Further information is requested

Comments

@arthurfiorette
Copy link
Owner

arthurfiorette commented Sep 8, 2022

Originally posted by @diegonogaretti in #304 (comment)

I just started using axios-cache-interceptor today and so far so good!
Unfortunately I have the same problem as @nolde, I'm caching all the GET requests but some have parameters and need to get invalidated/updated after a POST to the same endpoint, here an example:

Request ID generation (url parameters included)

generateKey: buildKeyGenerator(({url, method}) => `${method?.toUpperCase()}/${url}`)

My axios' request's interceptor (I have a global axios instance using react's context api)

client.interceptors.request.use(
        (config) => {
            setBackdrop({...backdrop, open: true, type: config.method === "get" ? loading" : "saving"});
            return config;
        },
        (error) => {
            setBackdrop({...backdrop, open: false});
            return Promise.reject(error);
        }
);

How can I invalidate/update cached GET requests in the interceptor? IDs are generated and not fixed like "list-posts" from your example.
Thanks in advance!

@arthurfiorette
Copy link
Owner Author

Hi @diegonogaretti!

If you are using auto generated IDs, you need to code a way to distinguish each request. Either by hardwritting each ID into your code or to use your custom id generator to get these other requests IDs inside your revalidation callback.

I moved your question to another issue to increase visibility to this frequent question. :)

@arthurfiorette arthurfiorette self-assigned this Sep 8, 2022
@arthurfiorette arthurfiorette added the question Further information is requested label Sep 8, 2022
@ghost
Copy link

ghost commented Sep 9, 2022

Thanks @arthurfiorette

I think I solved this by using a custom id generator and storing them in a useRef object which persists across rerenders.
I check in the interceptor if the request isn't a GET, if so I get all previous ids stored in the useRef object with the same endpoint and then I manually remove them from axios.storage in a loop.

Do you think it's good? Here is the code:

const ids = useRef<string[]>([]);
const client = setupCache(
    axios.create({
        baseURL: import.meta.env.DEV ? "dev api url" : "prod api url"
    }),
    {
        generateKey: buildKeyGenerator(({url, method}) => {
            let id: string = `${method?.toUpperCase()}/${url}`;
            if (method === "get" && !ids.current.includes(id)) ids.current.push(id);
            return id;
        }),
        headerInterpreter: defaultHeaderInterpreter,
        storage: buildWebStorage(sessionStorage, "axios-cache_")
    }
);
client.interceptors.request.use(
    (config) => {
        if (config.method !== "get") {
            let pos = import.meta.env.DEV ? 0 : 1;
            let endpoint = config.url!.includes("/") ? config.url!.split("/")[pos] : config.url!;
            ids.current.filter((id) => id.includes(endpoint)).forEach((id) => {
                client.storage.remove(id);
            });
        }
        return config;
    }
);

@arthurfiorette
Copy link
Owner Author

It seems fine. Good work 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

1 participant