Creating a User Model with Auto-Incremented Code in TypeScript and MongoDB

Arivuselvan Chinnasamy
3 min readMar 12, 2024

When building applications, it’s common to generate unique codes for users. In this tutorial, we’ll explore how to create a user model with an auto-incremented sequence number using TypeScript, MongoDB, and Mongoose.

Prerequisites

Before we dive in, make sure you have the following set up:

  1. Node.js and npm installed on your machine.
  2. MongoDB Atlas account or a local MongoDB server

Step 1: Project Setup

Start by initializing a new TypeScript project. Run the following commands in your terminal:

npm init -y
npm install typescript mongoose @types/mongoose ts-node

Create a tsconfig.json file to configure TypeScript:

{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"outDir": "./dist",
"rootDir": "./src",
"strict": true
},
"include": ["src/**/*.ts"],
"exclude": ["node_modules"]
}

Step 2: Counter Model

Create a counter.model.ts file for the counter model. This model will manage the sequence numbers:


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

export interface ICounter extends Document {
seq: number;
collectionName: string;
}
const counterSchema: Schema<ICounter> = new Schema({
seq: { type: Number, required: true },
collectionName: { type: String, required: true, unique: true },
});

export const Counter = mongoose.model<ICounter>('Counter', counterSchema);

Step 3: User Model

Now, create a user.model.ts file for the user model. This is where the magic happens with the auto-incremented code:


import mongoose, { Schema, Document } from 'mongoose';
import { Counter } from './counter.model';

export interface IUser extends Document {
name: string;
email: string;
password: string;
code: string;
}

const userSchema: Schema<IUser> = new Schema(
{
name: { type: String, required: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
code: { type: String },
},
{ timestamps: true }
);

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

// Check if the email is unique
const existingUser = await mongoose.models.User.findOne({ email: doc.email });
if (existingUser) {
throw new Error(`User with email "${doc.email}" already exists`);
}

// Find the counter document and update the sequence
const counter = await Counter.findOneAndUpdate(
{ collectionName: 'user' },
{ $inc: { seq: 1 } },
{ new: true, upsert: true }
);

if (!counter) {
throw new Error('Failed to get or create the counter document');
}

const newSeqNo = counter.seq;
const targetedLength = 5;
const padding = '0'.repeat(targetedLength - newSeqNo.toString().length);
const result = padding + newSeqNo;

doc.code = 'U' + result;
next();
} catch (error:any) {
next(error);
}
});

export const User = mongoose.model<IUser>('User', userSchema);

Step 4: MongoDB Connection

Create a dbConfig.ts file to handle the MongoDB connection:

import mongoose from 'mongoose';

const mongoURI = "your-mongodb-connection-string";

const connectDB = async () => {
try {
await mongoose.connect(mongoURI);
console.log('Connected to MongoDB');
} catch (error) {
console.error('Error connecting to MongoDB:', error);
process.exit(1);
}
};

export default connectDB;

Replace 'your-mongodb-connection-string' with your actual MongoDB connection string.

Step 5: Testing

Create a test.ts file to test the user model:

import connectDB from './db';
import { User } from './user.model';

const test = async () => {
try {
await connectDB();

const newUser = new User({
name: 'John Doe',
email: 'john@example.com',
password: 'securepassword',
});
await newUser.save();
console.log('User created successfully:', newUser);
} catch (error) {
console.error('Error creating user:', error);
} finally {
await mongoose.connection.close();
}
};

test();

Step 6: Run the Test Script

Execute the test script using the following command:

npx ts-node test.ts

This script connects to MongoDB, creates a new user, saves it, and logs the created user. Ensure your MongoDB server is running.

Output:

node-mongoose-usercode % npx ts-node test.ts
Connected to MongoDB
User created successfully: {
name: 'John Doe',
email: 'john@example.com',
password: 'securepassword',
_id: new ObjectId('65f004360a8a533df3193cce'),
createdAt: 2024-03-12T07:28:54.860Z,
updatedAt: 2024-03-12T07:28:54.860Z,
code: 'U00001',
__v: 0
}
node-mongoose-usercode %

Conclusion

Congratulations! You’ve successfully implemented a user model with an auto-incremented sequence number using TypeScript, MongoDB, and Mongoose. Feel free to integrate these models into your TypeScript Node.js project and tailor the solution to your needs.

Feel free to explore the full code on GitHub: Node Mongoose Usercode

Happy coding!

--

--