Tips for handling various mandatory fields for two different user roles within a unified userModel.ts file on a Next.js and MongoDB user registration API platform

Could you please review my code and provide any suggestions for improvement? I have two types of user roles, candidate and business, each with multiple unique fields. My goal is to consolidate all these fields into one userModel.ts file.

import mongoose from 'mongoose';

const userSchema = new mongoose.Schema({
  email: {
    type: String,
    required: true,
    unique: true,
  },
  password: {
    type: String,
    required: true,
  },
  role: {
    type: String,
    enum: ['candidate', 'business'],
    required: true,
  },
  // ... Other common fields for both roles
  // Define optional specific fields for each role (if any)
  candidateSpecific?: {
    // Candidate-specific fields (optional)
  },
  businessSpecific?: {
    // Business-specific fields (optional)
  },
});

export default mongoose.models.users || mongoose.model('users', userSchema);

Answer №1

Indeed, there are several enhancements you can implement to better manage the specific fields for each role. Utilizing Mongoose's mixed type for role-specific fields and ensuring they are only required or present based on the user's role can streamline the process.

Also, don't forget to utilize the pre method to define the user's role.

import mongoose, { Schema, Document } from 'mongoose';

interface IUser extends Document {
  email: string;
  password: string;
  role: 'candidate' | 'business';
  candidateSpecific?: {
    // Define candidate-specific fields here
    resume?: string;
    portfolio?: string;
  };
  businessSpecific?: {
    // Define business-specific fields here
    companyName?: string;
    companyWebsite?: string;
  };
}

const userSchema = new Schema<IUser>({
  email: {
    type: String,
    required: true,
    unique: true,
  },
  password: {
    type: String,
    required: true,
  },
  role: {
    type: String,
    enum: ['candidate', 'business'],
    required: true,
  },
  candidateSpecific: {
    type: Schema.Types.Mixed,
    default: {},
  },
  businessSpecific: {
    type: Schema.Types.Mixed,
    default: {},
  },
});

userSchema.pre('save', function (next) {
  const user = this as IUser;

  if (user.role === 'candidate') {
    user.businessSpecific = undefined;
  } else if (user.role === 'business') {
    user.candidateSpecific = undefined;
  }

  next();
});

export default mongoose.models.User || mongoose.model<IUser>('User', userSchema);

By following this approach, you can create instances like the following:

 const newUser = new User({
    email: 'example@example.com',
    password: 'securepassword',
    role: 'candidate',
    candidateSpecific: {
      resume: 'link_to_resume',
      portfolio: 'link_to_portfolio',
    },
  });
  
  
   const newUser = new User({
    email: 'info@company.com',
    password: 'securepassword',
    role: 'business',
    businessSpecific: {
      companyName: 'Company Inc.',
      companyWebsite: 'https://company.com',
    },
  });

Answer №2

Your analysis of the data indicates that it would be beneficial to handle candidate and business specific fields with separate models.

However, if you prefer to manage all data within one model, you can utilize Subdocuments and create a function for the required validator to ensure that candidateSpecific fields are present when role is candidate, and businessSpecific fields when role is business.

For instance:

import mongoose from 'mongoose';

// Define candidate schema to handle specific fields for candidates
const candidateSchema = new mongoose.Schema({
    whatBroughtYouToPikle: {
        type: String,
    },
    currentStatus: {
        type: String,
    },
    //...
});

// Define business schema to handle specific fields for businesses
const businessSchema = new mongoose.Schema({
    companyName: {
        type: String,
    },
    companySize: {
        type: String,
    },
    //...
});

// Create a unified user schema to handle all types of users
const userSchema = new mongoose.Schema({
    email: {
        type: String,
        required: true,
        unique: true,
    },
    password: {
        type: String,
        required: true,
    },
    role: {
        type: String,
        enum: ['candidate', 'business'],
        required: true,
    },
    // ... 
    candidateSpecific:{
        type: candidateSchema,
        required: function (){
            return this.role === "candidate";
        }
    },
    businessSpecific: {
        type: businessSchema,
        required: function (){
            return this.role === "business";
        }
    },
});

export default mongoose.models.User || mongoose.model<IUser>('User', userSchema);

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

The compiler throwing an error claiming that the indexOf method is not a valid

Currently, I am working on a simple form that collects user input and aims to validate the email field by checking for the presence of "@" and "." symbols. However, every time I attempt to run it, an error message stating that indexOf is not a function p ...

How can I style the options and optgroups of a select dropdown with CSS, focusing on padding and margins?

In my experience, I have found that padding or margin CSS properties only seem to affect the appearance of options within the select menu in Firefox browser. I attempted the same styling in Internet Explorer and Chrome but it did not have any effect. Is ...

What are the possible reasons for the connection failure between Mongodb collection and your application?

When attempting to connect with Mongoose, the connection is successful. However, when trying to connect with your application and MongoClient using this code provided in their documentation, it does not work. Why is the MongoDB collection not connecting th ...

Examining Vuex Mutations using Jest confirms no alteration in state

I am currently facing an issue with testing a namespaced Vuex module using Jest. Despite making mutations to the mocked state, I am not seeing any changes reflected. Below is the code for my addEvents mutation: addEvents: (state, infos) => { t ...

Issue: "contains method is not supported" in Ionic 2

I'm currently working on a code to validate the contents of my input field, but I've encountered an issue with using the contains function. Here's the TypeScript function I have written: checkFnameFunction(name){ if(name.contains("[a-z ...

Is there a way to show additional information beyond just the title in FullCalendar?

Hello, I am currently using the full calendar plugin and have a question. While I can display the title of events on my calendar, I would also like to display additional information from my database (such as full name or description) alongside the title. H ...

Eliminate screen flickering during initial page load

I've been developing a static website using NuxtJS where users can choose between dark mode and default CSS media query selectors. Here is the code snippet for achieving this: <template> <div class="container"> <vertical-nav /> ...

Updating a div using PHP elements

Currently, I'm using a webcam to capture images for a project related to learning. My goal is to showcase the recently taken photos. After taking a photo, it gets stored in a folder. To display all the collected photos within a <div>, I need to ...

Error message "Truffle 'Migrations' - cb is not a valid function"

I created a straightforward smart contract using Solidity 0.6.6 and now I'm attempting to deploy it on the BSC Testnet. Here's what my truffle-config.js file looks like (privateKeys is an array with one entry ['0x + privatekey']): netw ...

The reset function in Angular's template-driven form does not seem to be functioning properly when implemented using a component

Form Template Example <form #contactFormTemplate = "ngForm" (ngSubmit)="submitContactForm()"> <input type="text" class="form-control" name="name" [(ngModel)]="formData.name" ...

Having trouble with changing text in a link with an onclick event?

When I click on the link, I want the text to change to the second span. However, this functionality is not working. Code var reload = false; $('#change').click(function() { reload = !reload; $('#change').click(function() { ...

Sending JSON data to Flask triggers a 400 Bad Request response

I'm facing an issue with my POST request while trying to perform a LIKE operation using Mongo syntax. It keeps throwing the following error: HTTP/1.1 400 Bad Request Here is the POST request: curl -i -H "Content-Type: application/json" -X POST -d & ...

What are the advantages of combining a library (using Rollup or Webpack) instead of simply transpiling it with Babel?

When developing a library in JavaScript, what are the benefits of using tools like Rollup or Webpack for bundling rather than just transpiling with Babel? One potential advantage could be that by bundling, you ensure that your dependencies are packaged eff ...

p5.js experiencing issue: Uncaught TypeError - Unable to access property 'transpose3x3' due to null value

I have a simple website built with Flask where I am running several p5.js sketch animations, and everything is working smoothly. However, when I try to add a new sketch that utilizes WEBGL, I encounter the following error: Uncaught TypeError: Cannot read p ...

Provide the scope to the directive when calling the $uibModal.open method

I am interested in developing a custom directive that displays data based on the scope of its parent controller. Here is the directive's JavaScript code: (function () { 'use strict'; angular .module('blabla') ...

Determining Date Differences and Applying Query Conditions Simultaneously in Java Mongo Template

Hey everyone, I'm working on a query that needs to update the status to 'inprogress' for all tasks with an updated date more than 2 hours ago. Here's a sample query: { "_id" : "ATK-l64KC3vm", "nodeid" : "NOD-AJaodNfH", "acc ...

Unraveling deeply nested array objects in JSON with Java Script/jQuery

I need help working with a JSON file that looks like the following: {[ {"name":"avc"}, {"name":"Anna"}, {"name":"Peter"}, {"Folder":[ {"name":"John"}, {"name":"Anna"}, {"Folder":[ {"name":"gg"}, ...

The issue of dynamic select not sending the POST data

Having an issue with a form where the selected country and city are not being posted correctly. Despite different names in the form and php mailer script, both selections are coming through as the country. Here's the form: <select style="width: 6 ...

Enliven the character limit reaction by incorporating a thrilling shake animation when it reaches

I have implemented a feature in my component where if a user reaches the character limit, the component should shake. However, despite my efforts, the shaking effect is not working in the current code. const useStyles = makeStyles(() => ({ shake ...

End the HTML page once the Flash (SWF) animation comes to a close

I have successfully exported my flash file to an HTML page. How can I make the page close automatically once the flash animation is finished? While I can use actionscript to stop the animation, I need the entire page to shut down on its own. I attempted u ...