Javascript AJAX: Ensures that a promise-dependent form submission will always be successful

At last, I was able to achieve this:

function validate(data_to_validate, url, section)
{
        var datastr = "section=" + section + "&data=" + data_to_validate;
        return new Promise(function(resolve, reject) {
                $.ajax({
                        type:'GET',
                        url:url,
                        data:datastr,
                        success:function(response) { resolve(response); },
                        error:function(response) { reject(response); }
                });
        });
}

async function verify_submission()
{
        init(); // initializes some global variables
        personal_errors_count = 0; // count errors

        var dni_ctl = document.getElementById("frm_employee_dni");
        var dni = dni_ctl.value;

        dni_ctl.style.borderColor = "black";
        dni_ctl.style.backgroundColor = "none";


        const status = await validate(dni, validation_url, "dni")
                .then(output => validateStatus(dni_ctl, output)) // validateStatus() updates color and form control title
                .catch(error => validateStatus(dni_ctl, "error"));
        $.when(status).done(console.log("Errors: " + personal_errors_count));
        return false; // set for testing purposes, but always ignored.
}

Whenever the onsubmit event occurs, async function check_submit() is triggered. The validate(...) function returns a promise, which is handled with .then() and .catch() to manage both outcomes. However, even with incorrect fields, the form gets submitted.

I suspect that the form always gets submitted due to faulty code somewhere, but identifying it has been challenging.

Appreciate any assistance!

Answer №1

Let's say we have a form that needs validation using a promised-based approach. The function validar() performs the validation and takes about 3 seconds to complete (considering multiple fields). However, when implemented as shown below, it fails! Let's delve into the comments to understand why.

<form action="google.com" id="frm">
  <input id="txt">
  <button type="submit">submit</button>
</form>

<script>
  document.getElementById('frm').onsubmit = () => {
    var check = check_submit();
    console.log(check); //Promise {<pending>}
    console.log(check ? true : false) // evaluates to true! (check ? true : false) <-- true
    //The browser proceeds with the default behavior of submitting to google.com
  }

  function validar() {
    return new Promise(function(resolve, reject) {
      setTimeout(() => resolve(false), 3000)
    });
  }

  async function check_submit() {
    var result = validar(); // <-- this line DOES NOT WAIT for the promise from validar to be resolved 
    // instead, it uses the current value (Promise {<pending>}) immediately and returns it!
    return result;
  }
</script>

So how can we make it work properly? It's simple, just prevent the default behavior by unconditionally returning false in the onsubmit event and manually submit the form (if valid) once the promise is resolved.

<form action="google.com" id="frm">
  <input id="txt">
  <button type="submit">submit</button>
</form>

<script>
  document.getElementById('frm').onsubmit = () => {
    check_submit(); //<-- will handle our form submission process
    return false; //unconditionally preventing default behavior
  }

  function validar() {
    return new Promise(function(resolve, reject) {
      setTimeout(() => resolve(false), 3000)
    });
  }

  async function check_submit() {
    var result = await validar(); //<-- this line NOW WAITS (using await) for validar's promise to be resolved
    if (result) {
      alert('Submitting form as validar returned true')
      document.getElementById('frm').submit(); // manually submit since promise value was true
    } else
      alert('meh')
  }
</script>

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

Focusing on the final (but not ultimate) elements within a specified tag

I am facing a challenge with an HTML structure containing multiple instances of a certain element along with two p elements beneath each: <some_tag></some_tag> <p></p> <p></p> <some_tag></some_tag> <p> ...

Is it achievable to assign a various value to the data attribute of a transition object in Ember.js?

Is there a way to set the data object when transitioning from a route using the transitionTo method? Upon entering the target route, I noticed that the transition object in my model hook has an empty attribute data: {}. What is the purpose of this object ...

Optimizing Your CSS Loading Process for Production Environments

Lately, I've been loading a lot of JS and CSS files in my project. In an effort to boost my site's performance, I decided to use YUICompression integrated with Ant build. After each project build, it automatically creates a minified file by appen ...

Is sendFile causing an error due to an invalid JSON format?

Whenever I try to send a file to a client for download, I encounter an exception saying that the JSON is invalid. Is there a better way to send the file, perhaps using res.download and setting the content as JSON? I want to avoid using AngularJS FileSaver ...

What is the process of setting a function as a property value in the Vuex State of an object from a component?

Can someone assist me with incorporating a function into the property of an object as a value for the state in my Vuex store? I am currently restructuring some code for a website using vue.js and fullpage.js. I have moved my fullpage options to the vuex s ...

What is the best method for converting input files into FormData?

I recently created a form that allows users to upload both an audio file and an image file simultaneously. However, during testing, I noticed that the alert only displays basic data and does not include the form data. function PodcastUpload({ data }) { ...

Incorporating append and clone through a loop with jQuery

Is there a way to properly order div elements generated using .append() and .clone methods in a for loop? Despite creating the initial div before the loop, the order seems to be incorrect. The first div (class news0) is being displayed after the last div ( ...

Convenient methods in Three.js for easily detaching and attaching character weapons within a scene

I'm currently facing challenges while developing a first-person shooter game using Three.js. I've encountered major glitches with THREE.SceneUtils.detach() and THREE.SceneUtils.attach(), and I'm uncertain if they are the appropriate methods ...

creating dynamic applications using ant framework

I'm having some challenges while trying to develop JS applications with Ant. I have a directory named src and each subdirectory inside it is considered a "mini-app". When I iterate through each subdirectory using subant, I'm struggling to get ...

Display data from two arrays in real-time

The following data is available: "PensionPlanSummary": [ { "Type": "DefinedContributionPension", "Participants": [ { "Year": 2018, "Value": 425.0 } ...

Is Moment.js displaying time incorrectly?

When using moment.tz to convert a specific date and time to UTC while considering the Europe/London timezone, there seems to be an issue. For example: moment.tz('2017-03-26T01:00:00', 'Europe/London').utc().format('YYYY-MM-DD[T]HH: ...

Utilizing AngularJS repeaters to pass information into Foundation modals

I am currently working on creating a "members" page for a website that will feature 3 columns of pictures and names for each member. My goal is to allow users to click on a specific member's picture to access more detailed information about them throu ...

How can I efficiently store and access DOM elements in my React application to avoid constant re-fetching?

Is there a known pattern for storing references to both regular DOM elements and jQuery elements within a class? Despite the general advice against using jQuery with React, I needed the jQuery functions for my menu to function properly and did not have ti ...

"Is there a virtual keyboard available that supports multiple inputs and automatically switches to the next input when the maximum length

Looking to build a virtual keyboard with multiple inputs that automatically switch to the next input field after reaching the maximum length. Currently having an issue where I can only fill the first input and not the second one. Any assistance in resolvin ...

Can you help me figure out what is causing an issue in my code? Any tips on removing a collection from MongoDB

I'm currently facing an issue with deleting a collection from MongoDB using the Postman API. The update function in my code is working perfectly fine, but for some reason, the delete function is not working as expected. It keeps displaying an internal ...

Transforming the express app object into a data type instead of a regular variable

Currently, I am setting up my own TypeScript Express project and aiming to abstract the code for better organization. In my app.ts file, the code looks like this: import express from 'express' const app = express(); const port = 3000; require( ...

Verifying the presence of a value within an SQL table

I am currently working on developing a bot that requires me to save the commandname and commandreply in a database. Right now, I am using mySQL Workbench for this task. My goal is to verify if the commandname provided by the user already exists in the tab ...

Attempting to retrieve div measurements in vh/vw units rather than pixels

I'm currently working on an app where I want the divs to be resizable. In order to achieve this, I need to store the user's changes in my database. My main concern is how can I convert the units provided in pixels (px) to a different unit of mea ...

What is the best way to allow all authenticated routes to display the Devise ajax Login form?

I have successfully incorporated Devise to accept Ajax Login and have designed a form for logging in via ajax, displayed within a modal. However, I am only able to view the form and login when I set up event binders for specific buttons that activate the m ...

The conditional rendering issue in Mui DataGrid's renderCell function is causing problems

My Mui DataGrid setup is simple, but I'm encountering an issue with the renderCell function not rendering elements conditionally. https://i.sstatic.net/MEBZx.png The default behavior should display an EditIcon button (the pencil). When clicked, it t ...