Running the async function multiple times within a brief period can cause disruptions to the shopping cart

When operating my online store, I encountered a problem with the shopping cart functionality. It seems that if I rapidly increase the quantity of items in the cart by clicking too quickly, duplicates are generated in both the shopping cart and order list. I suspect there may be a bug in my code, and I wonder if it has something to do with the asynchronous function.

Please note that in this scenario, an API call is made every time an item is added, which is a requirement that cannot be changed at the moment.

async addProduct({ commit, state, dispatch, getters }, item) {
  try {
    if (getters.gotThisItemAlready(item)) {
      console.error("ITEM ALREADY HERE");
      dispatch("changeItemQuantity", { item, quantity: 1 });
      return;
    }

    let { order } = JSON.parse(JSON.stringify(state));

    item.quantity = 1;

    if (!order.items.length) {
      order = await API.createOrder([item]);
    } else {
      order.items.push(item);
      order = await API.updateExistingOrder(order);
    }

    order.items.forEach((item: any, index: number) => {
      const article = articles.find(
        (a: any) => a.articleID === item.articleID
      );
      if (article) {
        Vue.set(order.items, index, Object.assign({}, article, item));
      }
    });
    commit("updateOrder", order);
  } catch ({ message }) {
    console.error(message);
  }
},

async changeItemQuantity({ commit, state }, { item, quantity = 1 }: any) {
  try {

    let { order} = JSON.parse(JSON.stringify(state));

    order.items.forEach((i: any, index: number) => {
      if (i.articleID === item.articleID) {
        if (
          i.quantity + quantity > -1 &&
          i.quantity + quantity <= item.stock[0].stock
        ) {
          i.quantity += quantity;
        }
        if (i.quantity === 0) {
          order.items.splice(index, 1);
        }
      }
    });

    order = await API.updateExistingOrder(order);

    order.items.forEach((item: any, index: number) => {
      const article = articles.find(
        (a: any) => a.articleID === item.articleID
      );
      if (article) {
        Vue.set(order.items, index, Object.assign({}, article, item));
      }
    });
    commit("updateOrder", order);
  } catch ({ message }) {
    console.error(message);
  }
}

Answer №1

Avoid queuing up calls by ensuring that an item is not added multiple times in your function. Implement a mechanism to ignore additional inputs while the processing is ongoing within the addItem() function.

let isProcessing = false;
async function performTask() {
    if (isProcessing) {
        console.log('Currently busy. Please wait for the current task to finish.');
        return;
    }
    
    // Perform necessary operations
    isProcessing = true;
    console.log('Initiating complex operation');
    await new Promise((resolve, reject) => {
        setTimeout(resolve, 1000);
    });
    console.log('Operation completed');
    isProcessing = false;
}

performTask();
performTask();

Answer №2

Dealing with the same problem repeatedly can be frustrating. One effective solution is to immediately disable a button upon clicking, and then re-enable it once the API call finishes. If the request takes a while, incorporating a spinner into the disabled state could enhance user experience.

<button :disabled="isButtonDisabled" @click="addItem">Add Item</button>

Within your function, you can implement the following logic:

this.isButtonDisabled = true;
await performLongAPIRequest();
this.isButtonDisabled = false;

Don't forget to style your button[disabled] CSS appropriately to signal visually that the button is disabled.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is there a way to integrate a snap carousel in a vertical orientation?

I am looking to make a List utilizing the snap carousel component, but I'm having trouble getting it set up. Can anyone help me with this? ...

What is the best way to continuously execute the ajax request for downloading a pdf file?

if( $.isArray(certTypeReq) ){ $.each(certTypeReq,function(key,certType){ $.ajax({ url: baseUrl+"/user/certificate/getlink", type: 'GET', data: { 'certType' : certType}, ...

Firebase Cloud Function variables causing 'unidentified' output

While experimenting with firebase cloud functions, I'm encountering an issue with a constant error message stating that userID is undefined. It's preventing the function from running smoothly. https://i.sstatic.net/MsnsV.png Below is the databa ...

Is your server failing to respond to requests once there are too many within a session?

A web application I developed uses frequent $.ajax() calls to send and receive data between a virtual machine host and client. However, I have encountered a recurring issue where the connection cuts out after a certain number of consecutive calls within a ...

Building a scrollable dropdown menu with Bootstrap 5: A step-by-step guide

The search for suitable code examples for scrollable dropdown menus compatible with Bootstrap 5 has been challenging. Are there any contemporary methods available to achieve this functionality seamlessly? ...

Unable to locate and interact with a specific element within a dropdown menu while utilizing Protractor

I am currently facing an issue with selecting a checkbox from a dropdown in jq widgets. The code seems to work fine when the element is visible on the screen, but fails otherwise. I have tried various methods such as executeScript and scrollIntoView to bri ...

Testing external browser pages in an electron app with testcafe: A step-by-step guide

While conducting E2E testing with testcafe on an electron-vue application, I am facing a challenge during the authentication phase. When I connect to an external application and try to enter username and password for authentication, I encounter difficult ...

Implementing dynamic props in Vue2 component by passing arbitrary named variables

Having recently delved into Vue, I am facing a challenge that has left me scratching my head after consulting the documentation: I am struggling to pass an arbitrarily named variable as a prop to a component instance. As per my understanding, props serve ...

What steps should I take to resolve the issue with running npm start?

I am encountering an issue while using React and trying to run my application. When I execute "npm run start," I receive the following error message: npm ERR! Missing script: "start" npm ERR! npm ERR! Did you mean one of these? npm ERR! npm star # Mark ...

Navigating through multiple pages with React Native stack navigation

I'm currently in the process of developing a react native app and I'm facing some confusion with regards to page navigation. It appears that there is a glitch in the navigation flow, causing it to skip a page. <NavigationContainer> ...

Using JSON.parse on the output of BsonDocument.ToJson results in an error

When fetching information from MongoDB and sending it to the client, I encountered a dilemma: var retrievedBsonDocument = ... retrieve data from database ... var dtoObject = new Dto { MyBson = retrievedBsonDocument.ToJson() }; While trying to parse the M ...

Next.js App encounters a missing API route (The requested page is not found)

I have been working on a Next.js app and I created an api route for sending emails. Everything is functioning properly in my development environment. However, after deploying to production, I encountered a 404 error with the message "The page could not b ...

Tips for repeatedly clicking a button over 50 times using Protractor

Is it possible to click the same button more than 50 times using a loop statement in Protractor? And will Protractor allow this action? Below is my locator : var nudge= element(by.xpath("//a[@class='isd-flat-icons fi-down']")); nudge.click(); ...

Changing field names in Mongoose before inserting them into the database

I have a database schema set up as follows const UserSchema = new Schema({ first_name: "john", last_name: "doe" }) When data is received on my API route, it looks like this in the response body request.body = { firstName: "joh ...

Mastering the alignment of Material-UI Menu items

When using the menu and menu item components of material-ui to create a select dropdown menu, I encountered an unusual issue where the dropdown menu always expands to the left side of the box, as shown in the image below: https://i.stack.imgur.com/ykRrp.jp ...

Command handler for a Discord.js Music Bot

Currently facing challenges while trying to integrate a music bot into my command handler. This is the snippet of code I am using: delete require.cache[require.resolve(`./commands/${command}.js`)]; let commandFile = require(`./commands/${command}.js`) ...

The scroll functionality does not seem to be functioning as intended on mobile devices when

Hey there, I'm currently working on making my navbar sticky and applying it when the page is scrolled. The code I have works flawlessly on desktop, but unfortunately, it doesn't seem to work on the mobile version. Any suggestions? window.addE ...

Launching a modal in a new browser window with the help of JavaScript or PHP

I need to implement a feature where clicking a link opens a modal in a new tab and redirects the current page to a different link, similar to how retailmenot handles coupons. Here is the code snippet I am currently working with: <div onClick="myFunctio ...

Is it possible to adjust the center of rotation in THREE.js TrackballControls so that it is not located at the center of the canvas

I'm currently using TrackballControls within THREE.js. The issue I am facing is that the center of rotation always remains in the center of the canvas. Is there a way to adjust this and move the center of rotation upwards? Here are my failed attempts: ...

What could be causing res.redirect to fail?

I am currently facing an issue with making an http.post request from Angular to an API on the backend. After the post request, I am trying to redirect to another page but for some reason, the redirect is not working properly. I am looking for an alternat ...