Destroying cached component in case of an error using composition API

Hello,

I am using the keep-alive tag as this:

  <router-view v-slot="{ Component }">
    <keep-alive include="Feed">
      <component :is="Component" />
    </keep-alive>
  </router-view>

in feed component I have a logic that loads the data via API request, catches exception, shows the loading spinner and also error message if any. In short:

<template>
  <div v-if="state.isError"> {{ state.errorMessage }}</div>

  <div v-if="state.isLoading">Loading..</div>
  <div v-else-if="!state.isError">Data goes here! REMOVED FOR SIMPLICITY</div>
</template>

<script>
import FeedService from "./services/FeedService";
import { reactive, ref, onDeactivated, getCurrentInstance } from "vue";

export default {
  name: "Feed",
  setup(props, context) {
    const state = reactive({
      isLoading: true,
      isError: false,
      errorMessage: undefined,
      errorCode: undefined,
    });

    const feedService = new FeedService();
	// p.s. service returns result in format { isError, errorMessage, data }
	feedService.getData().then((result) => {
        state.isLoading = false;
        state.isError = result.isError;
        state.errorMessage = result.errorMessage;

        if (!result.isError) {
			// removed for code simplicity
			//myRefData = result.data;
        }
      });

    const internalInstance = getCurrentInstance();
    onDeactivated(() => {
      if (state.isError) {
		// How to destroy the instance if there was an error while loading the data?
		//this.destroy();
		//this.$destroy();
		//internalInstance.$destroy();
		//internalInstance.ctx.$destroy();
      }
    });

    return {
      state,
    };
  },
};
</script>

My goal is to make it so that if there was an error caught during the API call (timeout, bad request, 401 etc…) - then the page shall not be cached! What is the point of caching an error message and showing the user the message after reopening the page? :slight_smile:

I have read on multiple places that people used to use the this.$destroy(); method but it does not seems to work with composition API… So I also tried multiple other approaches. in onDeactived method which you can find earlier in the code… Nothing worked so far. Says that the methods do not exits.

So my question is either

  1. how to forbid caching errored-out component?
  2. how to destroy cached component if there is an error?

Whatever the option works…

p.s. I know that reloading the data when opening the cached page will work HOWEVER it sounds like an overhead/hack. I don’t want to write if/elses to check if there was an error before! I just want the instance not to be cached in the first place :slight_smile:

using vue@3.2.21

Using a key on your dynamic component should allow you to invalidate it. This is a pretty simplistic approach. There’s an RFC discussing a more flexible solution: https://github.com/vuejs/rfcs/pull/284

Sorry but I still don’t see how the cache policy or the keys would solve the issue I am describing.
The RFC describes the process of invalidation based on external policy. Policy defined outside of scope of the component.

What I would like to achieve is to apply the internal policy. Meaning component itself decides on the rules of invalidation. For example (see my initial post) when the data could not be retrived from the backend server the component needs to invalidate the cache or tell the Vue not to apply the caching to the page/component.

While two of the approaches achieve the same goal I think it’s important that we differentiate between them.

I have temporary solved my problem by basically writing a bunch of conditional logic on a page. If there is a better approach to the solution please provide some examples/links that I could follow…