Progress persists despite setbacks

Having some asynchronous code that needs to halt in case of error but continues to execute:

async saveCoupons({ state, rootState, dispatch, commit }) {
    const promises = []
    state.userCoupons.forEach(coupon => { 
        if (coupon.isNew && coupon.isUpdated) {
            // if the user is creating a new coupon
            promises.push(Vue.axios.post('/api_producer/coupons.json', coupon, { params: { token: coupon.token } }))
        } else if (!coupon.isNew && coupon.isUpdated) {
            // if the user is updating the coupon
            promises.push(Vue.axios.patch(`api_producer/coupons/${coupon.id}/`, coupon, { params: { token: coupon.token } }))
        }
    })
    try {
        await Promise.all(promises)
        dispatch('utilities/showModal', 'success', { root: true })
        dispatch('fetchProducerCoupons')
    } catch (err) {
        let couponToken = err.request.responseURL.split('token=')[1]
        commit('ADD_ERROR_ON_COUPON', couponToken)
        console.log(err)
    }
}

The current structure of the code functions, but it appears inefficient. The objective is to halt the execution of

dispatch('utilities/showModal', 'success', { root: true })
dispatch('fetchProducerCoupons')

If any of the API calls encounter an error. It is preferable to catch the error within the forEach loop to immediately access and handle the item rather than postponing it for later (as done with

{ params: { token: coupon.token } }
.

Answer №1

The optimal approach, in my opinion, would involve encapsulating the Vue.axios requests within a custom Promise. This way, if the requests encounter errors, you will still have access to the coupon tokens.

Here is an example implementation:

const promises = [];

promises.push(
  Vue.axios.post('/api_producer/coupons.json', coupon)
    .catch(() => { throw new Error(coupon.token) }));
    
Promise.all(promises).catch(tokens => {
  tokens.forEach(token => {
    // Handle error tokens here
  });
});

Answer №2

If you want to ensure the status of your API call, you can encapsulate it within another promise. Here is an example of how you can do this:

promises.push(

  new Promise((resolve, reject) => {

    Vue.axios.post('/api_producer/coupons.json', coupon, { params: { token: coupon.token } })
    .then((response) => {
      if (response.status !== 200) {
        coupon.error = true;
        reject();
      } else {
        resolve();
      }
    });

  })
);

Using the reject function will prevent the execution of the following two lines of code:

  dispatch('utilities/showModal', 'success', { root: true })
  dispatch('fetchProducerCoupons')  

Answer №3

Big shoutout to Moritz Schmitz v. Hülst & sklingler93 for their assistance in helping me restructure the code, which is now fully functional.

I'm curious if there's a way to streamline all of this using async/await exclusively... If anyone has any insights, I'd greatly appreciate seeing them :)

updateCoupons({ state, rootState, dispatch, commit }) {
    const operations = []
    state.userCoupons.forEach(coupon => {          
        if (coupon.isNew && coupon.isUpdated) {
            // for creating a new coupon
            operations.push(new Promise((resolve, reject) => {
                Vue.axios.post('/api_producer/coupons.json', coupon)
                    .then(response => resolve(response))
                    .catch(err => {
                        reject(err)
                        commit('ADD_ERROR_ON_COUPON', coupon.token)
                    })                        
            }))
        } else if (!coupon.isNew && coupon.isUpdated) {
            // for updating an existing coupon
            operations.push(new Promise((resolve, reject) => {
                Vue.axios.patch(`api_producer/coupons/${coupon.id}/`, coupon)
                    .then(response => resolve(response))
                    .catch(err => {
                        reject(err)
                        commit('ADD_ERROR_ON_COUPON', coupon.token)
                    })
            }))
        }
    })
    Promise.all(operations)
        .then(() => {
            dispatch('utilities/showModal', 'success', { root: true })
            dispatch('fetchProducerCoupons')
        })
        .catch(err => console.error(err))
},

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

Insert information into a nested array using Mongoose

I'm encountering an issue with my code, even though I know it may be a duplicate. Here is the snippet causing me trouble: exports.addTechnologyPost = function(req, res){ console.log(req.params.name); var query = { name: 'test ...

Utilizing internal PDF links in a Microsoft UWP application

In the process of developing a UWP app using javascript, I have created a list of links that are connected to PDF files stored locally in the app. The ultimate goal is to offer a collection of hands-free documentation for the Hololens (Windows AR) device. ...

Issue encountered in IE9 and IE10 when loading the angular library results in the "SCRIPT5007: Object expected" error for Angular JS

I am currently working on an AngularJS application that needs to be compatible with Firefox, IE 9, and IE 10. We are using the latest version of the AngularJS library (currently at 1.3.15). Our serverside is based on Java in the JavaEE platform, running on ...

Exploring the possibilities of integrating jQuery into Firefox extensions

Can someone provide guidance on effectively implementing jQuery within a Firefox extension? My research has not yielded any up-to-date methods that address the latest version of jQuery, and I am aware that directly including it via script tag may lead to c ...

Streamlining all icons to a single downward rotation

I am currently managing a large table of "auditpoints", some of which are designated as "automated". When an auditpoint is automated, it is marked with a gear icon in the row. However, each row also receives two other icons: a pencil and a toggle button. W ...

Encountering a Next.js application error while utilizing the button tag in conjunction with generating metadata

I keep encountering an issue with generateMetaData when trying to utilize the button tag. Can you help me resolve this problem? Currently, I am working with nextjs and I am unable to properly use the <button> tag. Whenever I implement generateMetaD ...

Revise my perspective on a modification in the backbone model

I am new to using Backbone and I am currently practicing by creating a blog using a JSON file that contains the necessary data. Everything seems to be working, although I know it might not be the best practice most of the time. However, there is one specif ...

Tips for troubleshooting a 422 (Unprocessable Entity) Error Response in a Vue/Laravel project

I'm currently struggling to connect the frontend of my simple Vue 3 and Laravel 8 contact form project with the backend. No matter what data values I pass, whether it's null or not, I keep getting a 422 (Unprocessable Entity) response without any ...

When utilizing the built-in filter in Angular 2 ag-grid, the Clear Filter button efficiently removes any text from the filter box without needing to refresh the

When using ag-Grid's default filter feature, I noticed that the clear filter button only clears the text box and does not automatically refresh the column, even when the 'clearButton' and 'applyButton' parameters are set to true. T ...

JavaScript API Response - conditional statement for handling a 'null' response

Does anyone have any suggestions for the following scenario: I have a response in .json format containing personal data of a person, who may or may not be assigned to a project. Here is an example response where the person is not assigned to a project: & ...

What is the most effective way to ensure that a child component only executes when a link is clicked on the Vue component?

There are two components in my code The first component, which is the parent component, looks like this : <template> <ul class="list-group"> <li v-for="item in invoices" class="list-group-item"> <div class="ro ...

Can you pinpoint the origin of the circular reference that triggers the error when using JSON.stringify?

I am encountering an issue where passing an object to JSON.stringify is resulting in the error "Converting circular structure to JSON," but I cannot pinpoint the exact reason for this. The object is being passed via server-side node.js. app.get('/&a ...

Generating unique ID's for data posting in PHP and JavaScript

I've developed a dynamic form that includes an "add more" button to generate an XML file for data import purposes. Users can fill out the form and add as many entries as needed by clicking on the "add more" button. The inputted data is then processed ...

Retrieve data from FileReader's onload event asynchronously in Javascript

Although this question has been asked numerous times before, I have reviewed the answers provided and still cannot get my code to work. I am working with Angular 2. I have input tags for file insertion. The file successfully reaches the component, but when ...

Getting started with html2canvas: A beginner's guide

So here's a seemingly simple question... I'm diving into new territory and stumbled upon http://html2canvas.hertzen.com with a straightforward tutorial. After successfully running the command npm install -g html2canvas, I hit a roadblock. Where e ...

Is it possible to calculate a variable within a dataset using existing data as a reference point?

Is there a way to dynamically compute some of the data variables in a Vue instance by referencing other variables and tracking their changes? new Vue({ el: '#root', data: { x: 1, y: x + 1 } }) <script src="https://cdnjs.cloudf ...

Clicking on a chart causes a null error in the 'removeHoverStyle' function

Here is a snippet of my base chart wrapper that utilizes ReactJS 16.8+ with ChartJS 2.0+ import React, { useEffect } from 'react'; import PropTypes from 'prop-types'; import Chart from 'chart.js'; import ChartDataLabels from ...

JavaScript XML Serialization: Transforming Data into Strings

When trying to consume XML in an Express server using express-xml-bodyparser, the resulting object is not very useful. This is the XML: <SubClass code="A07.0"/> <SubClass code="A07.1"/> <SubClass code="A07.2"/> <SubClass code="A07.3" ...

I have implemented a code snippet that verifies if the incoming week aligns with the existing week, triggering an alert accordingly

One of the challenges I faced was checking if a newly created week matched with an existing one, and then displaying an alert. Here's how I approached it: $scope.addWeek = function(type,newWeek,index){ var c = $scope.weekList.length + 1; var ...

The node application route appears to be malfunctioning

Recently delving into the world of node JS, I encountered an issue while working on my application with the following 3 files. http.createServer(app).listen(**app.get('port')**, function(){ The error message reads 'undefined is not a func ...