Home > Back-end >  Preventing axios multiple calls
Preventing axios multiple calls

Time:10-14

I use axios in my VueJS app. For the moment, in every component, I use a variable in every component to check is the user has already clicked on the button before launching the axios call. It leads to a lot of repetitive code, so I thought about wrapping my axios calls into a function "uniqueAxios", like this:

const urlsAPI = [];
const uniqueAxios = async (method, url, data) => {
  if (urlsAPI.includes(url)) {
    console.log('Already called!!');
    Promise.reject(new Error('Already called'));
  } else {
    urlsAPI.push(url);
    await axios[method](url, data)
      .then((res) => {
        console.log('OK');
        console.log(res);
        return Promise.resolve(res);
      })
      .catch((e) => {
        console.log('KO');
        console.log(e);
        return Promise.reject(e);
      });
  }
};

But when I use this function in my component, like this:

await uniqueAxios(
          'post',
          `${process.env.VUE_APP_API_URL}/XXX`,
        )
          .then((res) => {
            console.log(res);
          })
          .catch((e) => {
            console.log(e);

The console throws an error: TypeError: res is undefined. The API is contacted, though. It's just that I can't handle the then and the catch I had previously when I used axios directly.

I'm sure the wrapping uniqueAxios function is not correct. Does anybody know how I should handle this? Thanks in advance.

CodePudding user response:

You have multiple problem, the first is you return nothing in your function.

const uniqueAxios = async (method, url, data) => {
  if (urlsAPI.includes(url)) {
    console.log('Already called!!');
    Promise.reject(new Error('Already called'));
  } else {
    urlsAPI.push(url);
    return await axios[method](url, data) // You need to return the axios
      .then((res) => {
        console.log('OK');
        console.log(res);
        return Promise.resolve(res); // This line return inside the promise axios not the function
      })
      .catch((e) => {
        console.log('KO');
        console.log(e);
        return Promise.reject(e);
      });
  }
};

Second things is you await and do a then for nothing on nothing. Now with this change you can await your function like this and log a response.

const response = await uniqueAxios(
  'post',
  `${process.env.VUE_APP_API_URL}/XXX`,
  )
console.log(response)

CodePudding user response:

Actually I found a solution:

let urlsAPI = [];
const uniqueAxios = async (method, url, data) => {
  if (urlsAPI.includes(url)) {
    throw new Error('Axios already called');
  }
  urlsAPI.push(url);
  const t = await axios[method](url, data);
  urlsAPI = urlsAPI.filter((u) => u !== url);
  return t;
};
  • Related