Combining the powers of Express.js, Sequelize, and advanced form validation

As a beginner with Express and Sequelize, I am looking to utilize Sequelize's validation functionality for form submissions without having to duplicate validations on the frontend or rely on additional libraries like express-validator. Below is an example of what I am trying to achieve:

var signup = function(req, res) {
    res.render('signup', { title: 'Sign-up' });
}

router.get('/signup', signup);

router.post('/signup', function(req, res) {
    User.create({
        email: req.body.email,
        ...
    }).then(function(user) {
        req.flash('info', 'User created successfully.');
        res.redirect('/login');
    }).catch(function(err) {
        // [1] Need a solution to convert Sequelize error messages into a JSON object
        if (req.xhr) {
            res.json(err);
        }
        else {
            // [2] Alternative for non-JS browsers
            req.flash('error', err);
            signup(req, res);
        }
    });
});
  1. How can I efficiently handle [1] without manually formatting Sequelize error messages into JSON?
  2. What approach should be taken to process the JSON on the frontend in order to highlight fields with errors without manual intervention for each field?
  3. What is the recommended method to repopulate the form with submitted data? Despite extensive online searches, information on this topic is scarce and most sources suggest manually setting the value attribute in the template (which becomes cumbersome with various types of input fields). While AJAX submission may solve this issue, forms should ideally function without JavaScript as well in my opinion.

Thank you!

Answer №1

To improve your code structure, I suggest separating validation logic from database operations. This will make it easier to display validation errors clearly and reduce the overall complexity of your code.

One way to achieve this is by moving all logic to a separate file where you can define specific functions like in the following example:


router.post('/signup', createUser)

In the function createUser(req, res, next), you can handle the validation and creation process efficiently:


createForm.validate(req)
    .then(()=>{
        return createForm.create(req);
    })
    .then((createdUser) => {
        req.flash('info', 'User created successfully.');
        res.redirect('/login');
    })
    .catch((error)=> {

        if(error instanceof ValidationError) {
            req.flash('error', error);
            return signup(req, res);
        }
        next(error); //go to handle unexpected  error
    });

Answer №2

When working with Node Express Js, my suggestion is to utilize the Node package called Joi.

If you prefer not to use any external library, another option for validation is by using Sequelize. To begin, you must set up Sequelize migrations. When creating these migrations, ensure that primary keys, foreign keys, data types, uniqueness, and null constraints are defined.
If your tables already have these constraints and keys in place, then migrations can be skipped.

The next step involves creating Sequelize Models. While constructing models, make sure they accurately represent your migration/table structure. You can incorporate Sequelize validations within your models.

For example: User Migration:

module.exports = {
async up(queryInterface, Sequelize) {
    await queryInterface.createTable('users', {
        id: {
            allowNull: false,
            autoIncrement: true,
            primaryKey: true,
            type: Sequelize.INTEGER
        },
        email: {
            allowNull: false,
            type: Sequelize.STRING,
            unique: true
        }, // more fields...
      
    });
},
async down(queryInterface, Sequelize) {
    await queryInterface.dropTable('users');
}
};

Model:

module.exports = function(sequelize) {
return sequelize.define('users', {
    id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: DataTypes.INTEGER
    },
    email: {
        allowNull: false,
        type: DataTypes.STRING,
    },
    name: {
        allowNull: false,
        type: DataTypes.STRING(50),
        validate: { 
           len: [3, 55]
        }
    }, // additional fields...
}, {
    freezeTableName: true,
    timestamps: false
});

}

In the above instance, a validation was applied on the name field (minimum length: 3, maximum length: 50).
Various validation options offered by Sequelize include:

// List of possible validations
isAlpha: true,
isAlphanumeric: true,
isEmail: true,
max: 23,
min: 23, and more.

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

Guide on preventing selection with beforeSelectionChange when using the select All checkbox in ng-grid

When the select All checkbox in the header is clicked, the beforeSelectionChange function is called with a rowItem array. Unfortunately, there doesn't seem to be an option to disallow selection. I need to disable the checkbox for certain rows based on ...

Gathering information from the server once it has completed its processing phase

Looking to retrieve data from my server after processing it. Specifically, I want to transfer the processed information to the front end. Situation: A document gets uploaded to Google Cloud, data is extracted and stored in Firestore, then that extracted d ...

Is there a method to pre-load a CSS background image so that it can still be displayed even without an internet connection?

Situation: Imagine having a web app that shows an error message when trying to perform an action but fails due to a connectivity problem. The error dialogue has a CSS class with a background image that can't load because of the connection issue, res ...

How about checking the memory usage in Javascript?

Similar Question: Looking for a Javascript memory profiler I am curious about determining the memory consumption of variables in JavaScript. Could it be done at all? ...

Top spot for placing a file containing a polyfill to ensure cross-browser compatibility in JavaScript projects

Curious about the best location within a React / Redux app (built with create-react-app) to store custom polyfill files for browsers that do not support certain features. I specifically require Array.prototype.includes and String.prototype.startsWith, as ...

JavaScript has issues with undefined array elements

Even though there is data in bindInfo, the array elements in Bind are showing as undefined. Any recommendations? let bindinfo = { clientid: 1, clientname: 'Web Client', nowutc: now_utc, bindlist: Bindings(this.props.bindDetails) ...

React Intersection Observer not functioning properly

Hey there! I'm trying to create an animation where the title slides down and the left element slides to the right when scrolling, using the intersection observer. Everything seems to be fine in my code, but for some reason it's not working. Any t ...

How to assign a preset value to a text area in AngularJS

While working with PHP and AngularJS, I have a requirement to specify the default value for a textarea. I prefer not to utilize ng-init="textarea = ''" as the data to populate is extensive. Similarly, I want to avoid using AJAX to prevent additi ...

Combining Two Validation Methods for jQuery Validate Plugin

Seeking advice on how to incorporate custom validation methods from jQuery validate into another method for validating data. Specifically, I have a 'Document ID' field that can accept either CPF or CNPJ (Brazilian documents) and I need to validat ...

Guide to custom sorting and sub-sorting in AngularJS

If I have an array of objects like this: [ { name: 'test1', status: 'pending', date: 'Jan 17 2017 21:00:23' }, { name: 'test2', sta ...

Avoid closing the login modal/popup form if there is a validation error

Is there a way to prevent the popup login form from closing after submitting it if there is a validation error? I am working with node.js and ejs as my view engine. Login html form: <div class="modal"> <div class="modal__box" ...

Retrieving saved data from LocalStorage upon page reload

<div ng-repeat="section in filterSections"> <h4>{{ section.title }}</h4> <div class="checkbox" ng-click="loaderStart()" ng-if="section.control == 'checkbox'" ng-repeat="option in section.options"> <label ...

Using Typescript to establish a connection between ngModel and an object's property

Let's talk about how we can dynamically bind an input to an undefined property in an object. For example, we have an object named user: let user = {}; How can we bind an input to a property that doesn't exist yet? Like this: <input [(ngMode ...

Issues with displaying images in Fancybox

I've integrated FancyBox into my website, but I'm experiencing a minor issue. While the FancyBox works perfectly in Dreamweaver, it seems to malfunction in various browsers. As someone who is not well-versed in programming, I'm struggling t ...

Loading an ASP.net page on the client side

Can someone tell me the event for pageload on clientside? function onPageLoad() { setSelectedIndexTo(1); } I attempted to do this, however no changes occur. Appreciate any help. Thanks! ...

Exploring the Web: Navigating through Browser URLs and

As I work on constructing a web portfolio that integrates various smaller web apps I've developed in the past, I encountered an issue. The main page at route (/) contains links to these small web apps, such as the board-game app located at route (/boa ...

Parameterized query causing JavaScript error

As I struggle with this issue for more than a day now, a scenario unfolds where a user clicks on a link of a book name triggering me to read that book's name. Subsequently, an Ajax request is made to a Jersey resource within which a method in a POJO c ...

Whenever I attempt to import the "Highway" package, I encounter an error stating "Unexpected identifier."

After installing Highway through the terminal, I encountered an issue when running the script below: import Highway from '@dogstudio/highway'; import Fade from './transition'; const H = new Highway.core({ transition: { default: ...

Getting an Object in PostgreSQL without the need for square brackets wrapping when using Node.js and Express

I'm currently utilizing PostgreSQL alongside node-postgres: pool, Node.js, and express to execute some basic queries. The issue I encounter is that the returned object is wrapped within square brackets, but my preference is to receive it without them. ...

Is bower install failing to detect a local npm package?

After running bower install, I encountered the following error message: $ bower install module.js:340 throw err; ^ Error: Cannot find module 'minimist' at Function.Module._resolveFilename (module.js:338:15) at Function.Module._l ...