DEV Community

Krishna Kurtakoti
Krishna Kurtakoti

Posted on

Web Backend App: Adding a formatted Id to a document using Mongoose virtuals with MongoDB,Nest.js

Project ID format – PR0001

The reader is a class which returns the json response object.
The field "_formattedId" is a virtual field which does not exist in Database.
Instead, a number field "formattedId" stores the index of the Project.
So,if the "formattedId" value is 1,10,100, the value of the "_formattedId" will be "PR0001","PR0010","PR0100".
These values are created by passing the "formattedId" values to pad function with width and z as additional arguments.
[link]
Link: https://stackoverflow.com/questions/10073699/pad-a-number-with-leading-zeros-in-javascript
Code:
src\sme-project\objects\sme-project.dto.ts
import { Expose, Type } from "class-transformer";
import {
IsNotEmpty,
IsDefined,
MaxLength,
IsOptional,
ValidateNested,
IsString,
IsIn,
IsInt,
} from "class-validator";
import { Reader, Creator, Updater } from "../../common/base/base.dto";

export class SmeProjectDto extends Reader {

@Expose()
readonly _formattedId: string = "";

}

export class CreateSmeProjectDto extends Creator {
constructor() {
super(true);
}
@IsDefined()
@IsNotEmpty()
@IsString()
@MaxLength(20, { message: "FundsRequired is too long" })
@ApiModelProperty()
readonly fundsRequired: string;
}

src\sme-project\objects\sme-project.schema.ts
export class SmeProject extends Entity {
formattedId: number;
}

export interface ISmeProject extends SmeProject, IEntity {
id: string;
}

Only the fields in the Schema are stored in the database.Here "formattedId" field is stored in the database.

Code:
src\sme-project\objects\sme-project.schema.ts
import { Entity, IEntity, createModel } from "../../common/base/base.model";
import { Schema } from "mongoose";
import { pad } from "../sme-project.service";

export const SmeProjectSchema: Schema = createModel("SmeProjects", {
formattedId: { type: Number, required: true}
});

SmeProjectSchema.virtual("_formattedId").get(function() {
return this._formattedId = "PR" + pad(this.formattedId, 4, 0);
}
);

In the service class,we create another field "formattedId" which is equal to "total number of records + 1",since a new record is being created.
src/sme-project/sme-project.service.ts
Code:
import { Injectable } from "@nestjs/common";
import { Model } from "mongoose";
import { BaseService } from "../common/base/base.service";
import { ISmeProject } from "./objects/sme-project.schema";
import { InjectModel } from "@nestjs/mongoose";
import { CanLoadVirtual } from "../common/interfaces/can.load.virtual";

import { Paginate } from "src/common/interfaces/pagination";

export function pad(n, width, z) {
z = z || '0';
n = n + '';
return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n;
}

@Injectable()
export class SmeProjectService extends BaseService
implements CanLoadVirtual {
constructor(
@InjectModel("SmeProject")
private readonly smeProjectModel: Model
) {
super(smeProjectModel);
}
async doPreCreate(createDto: Partial): Promise {
let options: Paginate = {limit: 30, page: 1, sort: "_id"};
let query = null;
let _projects = await this.findAll(query,options);
createDto["formattedId"] = _projects.total + 1;
}

}
}
My Github Profile for code:
Please see the develop branch in my repo.
[Link]https://github.com/krishnakurtakoti/nestTwo

Top comments (0)