Home  >  Q&A  >  body text

Vue fetch is called twice

I have this code snippet:

export default defineComponent({
  name: "filter",
  props: {},
  setup() {
    const states = useCounterStore();
    return { states };
  },
  data() {
    return {
      items: [],
    };
  },
  methods: {},
  mounted() {
  fetch("http://localhost:3000/tags")
  .then((res) => res.json())
  .then((data) => {
    this.items = data;
    alert(data);
  })
  .catch((err) => console.log(err.message));
  },
});

fetch is called twice and I don't know why. Is there any solution?

P粉593649715P粉593649715290 days ago489

reply all(1)I'll reply

  • P粉269847997

    P粉2698479972024-01-04 11:27:32

    From the shared code, it appears that the component is being installed twice, so you may want to look at the component that is installing it.

    However, you can store the response so it is not fetched multiple times

    const tags = ref(null);
    const tagsError = ref(null);
    const getTags = () => {
      fetch("http://localhost:3000/tags")
        .then((res) => res.json())
        .then((data) => {
          tags.value = data;
          return tags;
        })
        .catch((err) => tagsError.value = err.message;
    }
    
    export default defineComponent({
      name: "filter",
      props: {},
      setup() {
        const states = useCounterStore();
        if(tags.value === null) {
          getTags().then(() => this.items = [...tags.value]);
        } else {
          this.items = [...tags.value];
        }
        return { states };
      },
      data() {
        return {
          items: [],
        };
      },
      methods: {},
    });
    

    Because tags is declared outside the component, it behaves like a global variable and is therefore stateful. Each time the component is set , it will check if the tag is loaded and then use the cached data, or load it and update the item afterwards.

    Some notes on this example...
    Ideally, such logic should be in a separate file and have better abstraction. For example, if you have multiple APIs, they can share this functionality, eg. const {status, data, error} = useApiCall('/tags'). And you can use tags directly instead of using items since the tag in the example is already ref. There may also be race conditions that can be resolved by tracking the status of API calls.

    reply
    0
  • Cancelreply