Executing both JavaScript Promise .then() and .catch concurrently

I've been working on converting my WordPress comments into an ajax-driven system.

Everything was going smoothly until I encountered a problem with the .catch() method triggering right after the .then() method.

Below is the code snippet...

Ajax engine

commentAPI: function(action, encoded, userID) {
    let self = this;

    return new Promise(function (resolve, reject) {
       //console.log("ajax call to " + self.ajaxURL + " with action " + action);

        jQuery.ajax({               
            url: self.ajaxURL,
            type: 'post',
            data: 'action='+action+'&data='+encoded,
            dataType: 'json',
            success: function(data, code, jqXHR) { resolve(data); },
            fail: function(jqXHR, status, err) { console.log('ajax error = ' + err ); reject(err); },
            beforeSend: function() {} //display loading gif
        });
    });
}, 

The method responsible for handling the comment form submission

handleReplyFormSubmit: function(form) {
    let self = this;

    this.removeErrorHtml(form);

    // Serialize form to name=value string
    const formdata = jQuery(form).serialize();

    // Validate inputs
    // * Wordpress doing this for now and providing error resonse 

    // Encode data for easy sending
    const encodedJSON = btoa( formdata );

    this.commentAPI('dt_submitAjaxComment', encodedJSON).then(function(response){
        console.log('firing then');

        if( response.error == true ) {
            self.printFormError(form, response.errorMsg);
        }

        else { 
            let html = response.commentHTML;
            console.log('html returned' + html)
            jQuery(form).append(html);
            Jquery(form).remove();
        }

    }).catch(function(err) {            
        console.log('firing catch');

        if( err !== undefined && err.length > 0 ) { 
            self.printFormError(form, err);
        }

        else { 
            self.printFormError(form, 'Unkown error');
        }
    });

    return false;
},

The code seems to be functioning as intended, but the catch method is getting triggered unnecessarily, causing frustration with error handling...

https://i.sstatic.net/FNopj.png

It's interesting to see how this part of the code gets executed:

console.log('firing catch')

While this one doesn't (within the ajax fail function):

console.log('ajax error = ' + err );

Am I missing something here?

Answer №1

Commitments

Oftentimes, a then function is executed first, followed by a catch function later on: indicating that an error occurred within the then handler and triggered the catch function. The catch handlers are executed in the following scenarios:

  • If there is an error during the asynchronous operation, leading to rejection of the Promise.
  • If an error occurs in any preceding then handler.

For example, consider the code snippet below:

Promise.resolve()
.then( () => {
  console.log('this will be called');
  throw new Error('bum');
  console.log('this wont be logged');
})
.catch(err => {
  console.log('this will be logged too');
  console.log(err); // bum related error
});

This code will result in logs from both the then and catch handlers being displayed.

Your script

In your then handler, the following code exists:

    else { 
        let html = response.commentHTML;
        console.log('html returned' + html)
        jQuery(form).append(html);
        Jquery(form).remove();
    }

Note the typo where Jquery is used instead of jQuery. This error is likely causing the catch block to execute.

In addition

Newer versions of jQuery return a promise directly from $.ajax(), eliminating the need to wrap it in another promise.

The revised code should look like this:

commentAPI: function(action, encoded, userID) {
    return jQuery.ajax({
        url: this.ajaxURL,
        type: 'post',
        data: 'action='+action+'&data='+encoded,
        dataType: 'json',
        beforeSend: function() {} //display loading gif
    });
},

This way, you can handle success and failure using then and catch directly within the commentApi method, rather than passing callbacks to resolve or reject a wrapping Promise.

Understanding ajax success parameters

The success callback takes three arguments, though Promises typically accept just one argument.

However, jQuery does pass these three arguments to the then handler. So, if necessary, you can access them within the handler as shown below:

this.commentAPI('dt_submitAjaxComment', encodedJSON).then(function(data, code, jqXhr){
 // the three arguments will be accessible here.
...
}

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 method to obtain the image path in a similar manner to item.src?

I am currently utilizing freewall.js, which can be found at The images will be generated dynamically. Therefore, the HTML structure will look like this: <div class="brick"> <img src="" width="100%"> </div> Here is the corresponding J ...

Any idea how to dynamically insert rows and columns into a table or div element?

Can anyone assist me with this task? I have successfully completed the visual process I intended to do. How can I achieve this structure using AngularJS? The data will be stored in Json format. When the "+" symbol is clicked in a certain direction, the fi ...

I require assistance in configuring the timing for an animation using Jquery

How can I adjust the timing (delay between two words) for this animation? If you need help, you can check out this link for guidance. Feel free to share your suggestions! ...

Integrate these scripts for seamless functionality: JavaScript/AJAX and PHP

Currently, I am in the process of learning all the languages involved here and facing a challenge while trying to merge two scripts to perform a single task. The goal is to select a branch from a form option list, transmit that value from the option to a ...

What is the method for incorporating choices into a schema field in Mongoose?

If my Schema is like this: var fooSchema = new Schema({ foo: String }); and I'm looking to implement select: false for foo, how can I achieve this without altering the initial structure? var fooSchema = new Schema({ foo: { type: String, select: ...

Apollo GraphQL has initiated the detection of a new subscription

My approach involves utilizing graphql-ws for subscribing to GraphQL events. I rely on the Observable interface to listen to these events. Although I can use the error callback to identify when a subscription fails to start, it is challenging to determine ...

Explore all potentialities within an array of objects by examining and contrasting their key values

Looking to run a specific math formula with three parameters using an array of objects in JavaScript. The scenario involves sports, where there are three possibilities: Team A (win), Team B (win), or Draw. There are three different bet websites offering o ...

What is the process for incorporating the !important declaration into a CSS-in-JS (JSS) class attribute?

I'm currently exploring the use of CSS-in-JS classes from this specific response in conjunction with a Material UI component within my React project. In order to override the CSS set by Bootstrap, I've decided to utilize the !important modifier. ...

Removing double double quotes for Javascript

My problem involves a string that represents longitude/latitude in the format of dd°mm'ss''W (note 2 single quotes after ss). To convert this string into its decimal representation, I am using the following code snippet: function dmsTodeg ...

Unable to set cookies properly

I am currently running a svc service on crm.mch.be. When a specific request is made, it returns a response with the following headers: Access-Control-Allow-Credentials: true Access-Control-Allow-Headers: X-Requested-With,Content-Type Access-Control-Allow- ...

Utilize Angular to inject an input from a component directly into the header of my application

I am looking to customize my Pages by injecting various components from different Pages/Components into the header. Specifically, I want to inject an Input search field from my content-component into the header Component. I initially attempted to use ng-Co ...

Whenever I navigate to a new page in my NEXTJS project, it loads an excessive number of modules

I am currently working on a small Next.js project and facing an issue where the initial load time is excessively long. Whenever I click on a link to navigate to a page like home/product/[slug], it takes around 12 seconds to load due to compiling over 2000 ...

I am encountering the error 'user.matchPassword is not a function' while making a call to my API using bcryptjs in my Node.js and Express application. Can someone help me understand why

const checkUserAuth = asyncHandler( async (req,res)=>{ const { email , password } = req.body; const foundUser = User.findOne({email}); if(foundUser && (await foundUser.verifyPassword(password))){ generate ...

The message from Vee-validate indicates that the validator 'required_if' does not exist within the system

I'm currently implementing vee-validate version 3 with Vue 2.7 in my project. Specifically, this is the entry in my package.json file for vee-validate: "vee-validate": "^3.4.5", My issue lies with getting the required_if rule to f ...

Issue with disabled button in Angular 2 when using Chrome's autocomplete feature

In a basic login form, the login button is initially disabled with the following code: [disabled]="!password || !loginName" When Chrome's autocomplete feature fills in the values for loginName and password, the button remains disabled after the pa ...

Updates to class variable values in jQuery are failing to take effect

Attempting to create my first JavaScript class has presented some challenges, specifically when it comes to updating a class variable. Despite hours of testing different approaches, I still can't seem to get it right! function ClassName(productId) { ...

Exploring the wonders of Node.js, Redis, and Express.js while navigating through the enchanting world of Asynchronous

Hello there, I must confess that this is a whole new realm for me... Here is what we've got: app.get('/user/:user_id/followings', function(req, res) { var response = {} , userId = req.params.user_id , ids = req.param(' ...

placeholder for dropdown selection in Vue.js version 2.0.0

Currently, I am in the process of developing a web application using vuejs 2.0. In order to create a straightforward select input, I employed the following code: <select v-model="age"> <option value="" disabled selected hidden>Select Age&l ...

Type of Angular Service Issue: string or null

I'm encountering a persistent issue with my Angular code, specifically while calling services in my application built on Angular 13. The problem arises when trying to access the user API from the backend, leading to recurrent errors. Despite extensive ...

Utilize a variable within an HTML attribute

Currently utilizing Angular and I have the following HTML snippet <input onKeyDown="if(this.value.length==12 && event.keyCode!=8) return false;"/> Is there a way for me to incorporate the variable "myNum" instead of the ...