How to return the fields defined by the interface not by the mongoose schema - node.js

How can I return "id" insted of "_id" and without "__v" to the client with express, mongoose and TypeScript?
My code below:
Interface
export default interface Domain {
name: string;
objects: DomainObject[]
}
Creation Interface
export default interface DomainCreate {
name: string
}
Mongoose Model
const DomainSchema = new Schema<Domain>({
name: { type: String, required: true },
});
const DomainModel = mongoose.model<Domain>("Domain", DomainSchema);
export { DomainModel, DomainSchema };
Service
export default class DomainService {
public async create(params: DomainCreate): Promise<Domain> {
const domainModel = new DomainModel<Domain>({name: params.name, objects: []});
const domainCreated = await domainModel.save().then();
return domainCreated;
}
}
Controller (POST)
#Post()
#SuccessResponse("201", "Created")
#Response<ValidateErrorJSON>(422, "Validation Failed")
#Response<UnauthorizedErrorJson>(401, "Unauthorized")
#Security("api_key")
public async createDomain(#Body() requestBody: DomainCreate): Promise<Domain> {
const createdDomain = await new DomainService().create(requestBody);
if (createdDomain) this.setStatus(201);
else this.setStatus(500);
return createdDomain;
}
Test:
POST http://localhost:3000/domains
{
"name": "D1"
}
Response:
{
"name": "D1",
"_id": "6291e582ade3b0f8be6921dd",
"__v": 0
}
Expected response:
{
"name": "D1",
"id": "6291e582ade3b0f8be6921dd"
}

There can be different ways to do it, but you can choose normalize-mongoose. It will remove _id, __v and gives you id;
So, in your schema you can add this plugin like this:
import normalize from 'normalize-mongoose';
const DomainSchema = new Schema<Domain>({
name: { type: String, required: true },
});
DomainSchema.plugin(normalize);
const DomainModel = mongoose.model<Domain>("Domain", DomainSchema);
export { DomainModel, DomainSchema };

Related

Create class default api Restful nodejs with Typescript

I am new in nodejs with typescript, and I want create a class with methods that recive the model mongoose as params and make basics request to database like, save, find, findOneById, findOneByIdAndUpadate etc
Here my model below
import { Document, Schema, model } from 'mongoose'
export interface ISimulator extends Document{
name: string;
speedways: string[];
categorys: string[];
cars: string[];
}
const schema = new Schema({
name: { type: String, required: true },
speedways: [
{ type: String }
],
categorys: [
{ type: String }
],
cars: [
{ type: String }
]
})
export const Simulator = model<ISimulator>('simulator', schema)
What I want Its samething like this
import { model } from 'mongoose'
export default class DefaultRestful {
getall( mdl: model ) {
const getall = mdl.find()
res.status(200).send(getall)
}
}
but a recive the errors " model refers to a value, but is being used as a type here.
How Can I make this work?

Get all data from subdocument via graphql

Model
const mongoose=require('mongoose');
const CustomerGeneralInformation = require('./CustomerGeneralInformation').schema;
const CustomerContact = require('./CustomerContact').schema;
const CustomerFinance=require('./CustomerFinancial').schema;
const CustomerPersonalData=require('./CustomerPersonalData').schema;
const CustomerIdentification=require('./CustomerIdentification').schema;
const Schema=mongoose.Schema;
const CustomerSchema=new Schema({
generalInformation: [CustomerGeneralInformation],
contactData: [CustomerContact],
financialData:[CustomerFinance],
personalData:[CustomerPersonalData],
identificationData:[CustomerIdentification]
});
module.exports=mongoose.model('Customer',CustomerSchema);
Graphql Schema
const RootQuery=new GraphQLObjectType({
name:'RootQueryType',
fields:{
customers:{
type: new GraphQLList(CustomerType),
resolve(parent,args){
return customer.find({});
}
}
}
});
GraphiQl
{
customers
{
id
generalInformation{
purposeOfBusiness
}
contactData{
phone
email
countryResidence
mailbox
houseNo
zip
city
}
financialData{
taxNo
countryTaxation
refBankIban
StringrefBankBic
refBankIban
}
}
}
Result
{
"data": {
"customers": [
{
"id": "5fa0f8ea4e028a2cf8d24c3f",
"generalInformation": {
"purposeOfBusiness": null
},
"contactData": {
"phone": null,
"email": null,
"countryResidence": null,
"mailbox": null,
"houseNo": null,
"zip": null,
"city": null
},
"financialData": {
"taxNo": null,
"countryTaxation": null,
"refBankIban": null,
"StringrefBankBic": null
}
}
]
}
}
SO I have created a customer model which have an id(autogenerated by mongodb) and 5 other fields of schema type.
I have used graphql for creating apis.
Everything is working fine, I have created mutations to add data, its all tested in mongo that data is being saved.
But if you check my graphql output I am unable to query subdocuments, it shows null. I want list of all subdocuments with data.
PlEASE HELP
I had tried this way and its working perfectly,
Firstly as you are passing the whole model in your new Customer model so instead of that I just have stored the ID as a reference.
const CustomerSchema = new mongoose.Schema(
{
generalInformation: {
type: mongoose.Schema.Types.ObjectId,
ref: "GeneralInfo"
},
contactData: { type: mongoose.Schema.Types.ObjectId, ref: "ContactData" },
financialData: {
type: mongoose.Schema.Types.ObjectId,
ref: "FinacialData"
},
personalData: { type: mongoose.Schema.Types.ObjectId, ref: "PersonalData" }
},
{
timestamps: true
}
);
After that, for CustomerType, I had done this
const CustomerType = new GraphQLObjectType({
name: "Customer",
fields: () => ({
id: { type: GraphQLID },
customerContact: {
type: CustomerContactType,
resolve(parent, args) {
return CustomerContact.findById(parent.contactData);
}
},
generalInformation: {
type: CustomerGeneralType,
resolve(parent, args) {
return CustomerGeneral.findById(parent.generalInformation);
}
},
financialData: {
type: CustomerFinanceType,
resolve(parent, args) {
return CustomerFinance.findById(parent.financialData);
}
},
personalData: {
type: CustomerPersonalType,
resolve(parent, args) {
return CustomerPersonal.findById(parent.personalData);
}
}
})
});
And them for RootQuery
customers: {
type: new GraphQLList(CustomerType),
resolve(parent, args) {
return Customar.find({});
}
}
and here is my Query:
{
customers{
id
generalInformation{
purposeOfBusiness
}
customerContact{
phone
email
countryResidence
}
financialData{
taxNo
}
}
}
And Output
{
"data": {
"customers": [
{
"id": "5fa3fe066f0fda0568e56456",
"generalInformation": {
"purposeOfBusiness": "Test Purpose"
},
"customerContact": {
"phone": "123456798",
"email": "test#demo.com",
"countryResidence": "Pak"
},
"financialData": {
"taxNo": "120033244"
}
}
]
}
}

how to join two schema in nestjs?

I have two schemas like
feature.schema.ts
`import * as mongoose from 'mongoose';
import { settings } from '../_settings';
export const FeatureSchema = new mongoose.Schema({
feature_name :{
type : String
},
module_id :{
type : mongoose.Schema.Types.ObjectId,
ref : 'Modules'
},
status :{
type : String,
default: false
}
}, {...settings.options, collection: 'Features'}
);`
and menus.schema.ts
import * as mongoose from 'mongoose';
import { settings } from '../_settings';
export const MenusSchema = new mongoose.Schema({
name :{
type : String
},
feature_id: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Features',
},
status :{
type : String
}
}, {...settings.options, collection: 'Menus'}
);
i try to join menus with feature, try to join in menus.service.ts like this
import { HttpException, HttpStatus, Injectable } from '#nestjs/common';
import { InjectModel } from '#nestjs/mongoose';
import { Model } from 'mongoose';
import { IDMenus, IDFeature } from '#core/interfaces';
import { MenusDto, FeatureDto } from '#core/dto';
var ObjectId = require('mongoose').Types.ObjectId;
#Injectable()
export class MenusService {
constructor(#InjectModel('Menus') private dataModel :Model<IDMenus>,
#InjectModel('Features') private ftModel :Model<IDFeature> ) {}
async findjoin(): Promise<IDMenus[]> {
return this.dataModel.find().populate('Features.feature_id')
.exec();
}
}
its result show no error,but don't get join result why ?
the result is
{
"_id": "5d6f606bbd12ad52b7ec618f",
"name": "Inventry",
"feature_id": "5d6f5d22bd12ad52b7ec618e",
"status": "TRUE",
"createdAt": "2019-09-04T06:57:47.212Z",
"updatedAt": "2019-09-04T06:57:47.212Z",
"id": "5d6f606bbd12ad52b7ec618f"
}
how to get the join result,this is correct way of join?
return await inside async function like this: return await this.dataModel.find().populate('feature_id').exec()

How to add a validator to an existing collection via node.js mongodb driver?

Here is a code where I'm trying to add a validator to an existing collection.
const { MongoClient } = require("mongodb")
const schema = {
$jsonSchema: {
bsonType: "object",
additionalProperties: false,
required: ["name"],
properties: {
_id: {
bsonType: "objectId"
},
name: {
bsonType: "string"
}
}
}
}
const main = async () => {
const client = await MongoClient.connect(
"mongodb://localhost",
{ useNewUrlParser: true }
)
const db = client.db("t12")
// await db.createCollection("test", { validator: schema })
await db.createCollection("test")
await db.admin().command({ collMod: "test", validator: schema })
await db.collection("test").createIndex({ name: 1 }, { unique: true })
await db.collection("test").insertOne({ name: "t1" })
await db.collection("test").insertOne({ value: "t2" }) // should fail
const all = await db
.collection("test")
.find({})
.toArray()
console.log(all)
await client.close()
}
main().catch(err => console.error(err))
It fails:
max7z#mbp t12__npm__mongodb (master)*$ node test/1.js
{ MongoError: ns does not exist
at /Users/max7z/projects/t/t12__npm__mongodb/node_modules/mongodb-core/lib/connection/pool.js:581:63
at authenticateStragglers (/Users/max7z/projects/t/t12__npm__mongodb/node_modules/mongodb-core/lib/connection/pool.js:504:16)
at Connection.messageHandler (/Users/max7z/projects/t/t12__npm__mongodb/node_modules/mongodb-
ok: 0,
errmsg: 'ns does not exist',
code: 26,
codeName: 'NamespaceNotFound',
name: 'MongoError',
[Symbol(mongoErrorContextSymbol)]: {} }
^C
If I create the collection with that schema it works, but when I'm trying to add a vatidator via collMod, it fails.
How to add a validator to an existing collection via collMod command?
I created a function like
const updateValidator = async (collectionName, newValidator) => {
return db.command({
collMod: collectionName,
validator: newValidator,
validationLevel: "moderate",
validationAction: "warn"
});
}
The problem with db.command is that is replaces the whole validation schema. Therefore you need access to the current schema of the collection. As I did not found the function db.getCollectionInfos in the nodejs library I added the posibility of passing it as a parameter.
In my case I get it from other migration module with a require. E.g.
const currentValidator = require("migration-file-where-I-defined-the-previous-schema").schema.validator;
In the required file I have some initial schema like:
module.exports.schema = {
validator: {
$jsonSchema: {
bsonType: "object",
required: ["name"],
properties: {
name: {
bsonType: "string",
maxLength: 300,
minLength: 3,
description: "Must be a string and is required"
},
created: {
bsonType: "date",
description: "Date when it was created"
},
deleted: {
bsonType: "date",
description: "Date when it was deleted"
}
}
},
}
};
Then I create a merge of the new schema and that will be enough. E.g.
const updatedValidator = Object.assign({}, currentValidator);
updatedValidator.$jsonSchema.properties.new_attribX = {
enum: ["type1", "type2"],
description: "State of the tenant related to its life cycle"
};
updatedValidator.$jsonSchema.required.push('new_attribX');
updateValidator("mycollection", updatedValidator)
.then(next)
.catch(console.error);
This will replace the previous schema with the new one which has the changes applied. For me, this was enough, but bear in mind that when you have existing data that needs to be updated with new data, then you need to update them with something like
collection.updateMany({'new_attribX': {$exists : false}}, {$set: {'new_attribX': 'type1'}});
Which for that data which has not that attribute (new_attribX) it should add them kind of this initial default value: type1.
I hope it helps.
The problem was in that line:
await db.admin().command({ collMod: "test", validator: schema })
The right way to do it:
await db.command({ collMod: "test", validator: schema })

How to create schema using model interfaces with type script mongoose

In my project using technologies are Nodejs,Mongoose, Express,Type script
I want to create below-mentioned JSON format collection in Mongodb
{
"emp_id": "001",
"login_id": "venue#abc.com",
"password": "venue123",
"role_id": 6,
"role_name": "TechLead",
"emp_ext": 456;
"leave_details": {
"leave_transactions": [
{
"leave_from_date": "14-10-2016",
"leave_from_part": "noon",
"leave_to_date": "16-10-2016",
"leave_to_part": "full",
"total_no_of_days": 2.5,
"leave_approved_by_id": "87",
"leave_approved_date": "14-10-2016",
"leave_applied_on": "13-10-2016",
"leave_status": "approved",
"leave_type": "EL",
"leave_desc": "going to hometown"
},
{
"leave_from_date": "18-11-2016",
"leave_from_part": "full",
"leave_to_date": "19-11-2016",
"leave_to_part": "full",
"total_no_of_days": 2,
"leave_approved_by_id": "115",
"leave_approved_date": "17-11-2016",
"leave_applied_on": "17-11-2016",
"leave_status": "approved",
"leave_type": "CL",
"leave_desc": "not feeling well",
"rejected_reason":""
}
]
}
}
To create above structure created below model interfaces and classes
import mongoose = require("mongoose");
import IJoiningDetailsModel = require('./JoiningDetailsModel');
import ILeaveDetailsModel = require('./LeaveDetailsModel');
interface EmployeeMasterModel extends mongoose.Document {
emp_id: number;
login_id: string;
name: string;
password: string;
role_id: number;
role_name: string;
emp_ext: number;
leave_details: ILeaveDetailsModel;
}
export = EmployeeMasterModel;
import IEmployeeMasterModel = require('./interfaces/EmployeeMasterModel');
import JoiningDetailsModel = require('./JoiningDetailsModel');
import IJoiningDetailsModel = require('./interfaces/JoiningDetailsModel');
import ILeaveDetailsModel = require('./interfaces/LeaveDetailsModel');
class EmployeeMasterModel {
private employeeModel: IEmployeeMasterModel;
constructor(employeeModel: IEmployeeMasterModel) {
this.employeeModel = employeeModel;
}
get name (): string {
return this.employeeModel.name;
}
get email (): string {
return this.employeeModel.login_id;
}
get password (): string {
return this.employeeModel.password;
}
get leave_details (): ILeaveDetailsModel {
return this.employeeModel.leave_details;
}
}
Object.seal(EmployeeMasterModel);
export = EmployeeMasterModel;
import mongoose = require("mongoose");
import mongoose = require("mongoose");
import ILeaveTransactionModel = require('./LeaveTransactionModel');
interface LeaveDetailsModel extends mongoose.Document {
leaveTransactionModel: ILeaveTransactionModel;
}
export = LeaveDetailsModel;
import ILeaveDetailsModel = require('./interfaces/LeaveDetailsModel');
import ILeaveTransactionModel = require('./interfaces/LeaveTransactionModel');
class LeaveDetailsModel {
private leaveDetailsModel: ILeaveDetailsModel;
constructor(leaveDetailsModel: ILeaveDetailsModel) {
this.leaveDetailsModel = leaveDetailsModel;
}
get leaveTransactionModel (): ILeaveTransactionModel {
return this.leaveDetailsModel.leaveTransactionModel;
}
}
Object.seal(LeaveDetailsModel);
export = LeaveDetailsModel;
import mongoose = require("mongoose");
interface LeaveTransactionModel extends mongoose.Document {
leave_from_date:Date;
leave_from_part : string;
leave_to_date : Date;
leave_to_part :string;
total_no_of_days :number;
leave_type :string;
leave_desc:string;
rejected_reason:string;
leave_approved_by_id:number;
leave_approved_date:Date;
leave_applied_on:Date;
leave_status:string;
}
export = LeaveTransactionModel;
import ILeaveTransactionModel = require('./interfaces/LeaveTransactionModel');
class LeaveTransactionModel {
private leaveTransactionModel: ILeaveTransactionModel;
constructor(leaveTransactionModel: ILeaveTransactionModel) {
this.leaveTransactionModel = leaveTransactionModel;
}
get leave_from_date (): Date {
return this.leaveTransactionModel.leave_from_date;
}
set leave_from_date(leave_from_date : Date){
this.leaveTransactionModel.leave_from_date = leave_from_date;
}
get leave_from_part (): string {
return this.leaveTransactionModel.leave_from_part;
}
get leave_to_date (): Date {
return this.leaveTransactionModel.leave_to_date;
}
get leave_to_part (): string {
return this.leaveTransactionModel.leave_to_part;
}
get total_no_of_days () : number{
return this.leaveTransactionModel.total_no_of_days;
}
get leave_type (): string {
return this.leaveTransactionModel.leave_type;
}
get leave_desc (): string {
return this.leaveTransactionModel.leave_desc;
}
get rejected_reason (): string {
return this.leaveTransactionModel.rejected_reason;
}
get leave_status (): string {
return this.leaveTransactionModel.leave_status;
}
get leave_approved_by_id () : number{
return this.leaveTransactionModel.leave_approved_by_id;
}
get leave_approved_date (): Date {
return this.leaveTransactionModel.leave_approved_date;
}
get leave_applied_on (): Date {
return this.leaveTransactionModel.leave_applied_on;
}
}
Object.seal(LeaveTransactionModel);
export = LeaveTransactionModel;
Schema class
import DataAccess = require('../DataAccess');
import IEmployeeMasterModel = require("./../../model/interfaces/EmployeeMasterModel");
var mongoose = DataAccess.mongooseInstance;
var mongooseConnection = DataAccess.mongooseConnection;
class EmployeeMasterSchema {
static get schema () {
// Employee leave transactions(request/approve/cancel) schema declaration
var LeaveTransactionsSchema = mongoose.Schema({
leave_from_date: {
type: Date,
required: false
},
leave_from_part: {
type: String
},
leave_to_date: {
type: Date,
required: false
},
leave_to_part: {
type: String
},
total_no_of_days: {
type: String,
required: false
},
leave_type: {
type: String,
required: false
},
leave_desc: {
type: String,
required: false
},
rejected_reason: {
type: String
},
leave_approved_by_id: {
type: Number,
required: false
},
leave_approved_date: {
type: Date
},
leave_applied_on: {
type:Date,
required: false
},
leave_status: {
type: String,
required: false
}
});
// Employee leave details schema declaration
var LeaveDetailsSchema = mongoose.Schema({
leave_transactions: {
type: [ LeaveTransactionsSchema ]
}
});
// Employee master schema declaration
var schema = mongoose.Schema({
emp_id : {
type: Number,
required: false
},
login_id: {
type: String,
required: false
},
password: {
type: String,
required: false
},
role_id: {
type: Number
},
role_name: {
type: String
},
emp_ext: {
type: Number
},
leave_details: {
type: [ LeaveDetailsSchema ]
}
});
return schema;
}
}
var schema = mongooseConnection.model<IEmployeeMasterModel>("employee", EmployeeMasterSchema.schema);
export = schema;
when i get request below method gets called ,for testing purpose setting data to ILeaveTransactionModel but when i try to set the ILeaveTransactionModel to not working ... How to set ILeaveTransactionModel into ILeaveDetailsModel.thanks in advance
import express = require("express");
import LeaveTraBusiness = require("./../app/business/LeaveTraBusiness");
import IBaseController = require("./BaseController");
import LeaveTransactionModel = require("./../app/model/LeaveTransactionModel");
import ILeaveDetailsModel = require("./../app/model/interfaces/LeaveDetailsModel");
import ILeaveTransactionModel = require("./../app/model/interfaces/LeaveTransactionModel");
// tslint:disable-next-line:one-line
export class LeaveTraController implements IBaseController<LeaveTraBusiness>{
leaveTra :any;
create(req: express.Request, res: express.Response): void {
try {
console.log(req.body.leave_desc);
this.leaveTra = <ILeaveTransactionModel>{
leave_from_date:new Date(),
leave_from_part : "Full",
leave_to_date : new Date(),
leave_to_part :"half",
total_no_of_days :5,
leave_type :"SL",
leave_desc:"No comme",
rejected_reason:"No comme",
leave_approved_by_id:121,
leave_approved_date:new Date(),
leave_applied_on:new Date(),
leave_status:"Active"
};
console.log(JSON.stringify(this.leaveTra));
let leaveTraBusiness = new LeaveTraBusiness();
//Here i want to set leaveTra to ILeaveDetailsModel
let leaveDetailsModel : <ILeaveDetailsModel>{leaveTra};
leaveTraBusiness.create(leaveDetailsModel, (error, result) => {
if (error)
res.send({"error": "error"});
else
res.send(result);
});
}
catch (e) {
console.log(e);
res.send({"error": "error in your request"});
}
}
}
Sorry, I did mistake in setting "leaveTra" to , below code solved my problem
let leaveDetailsModel = {
leaveTransactionModel: leaveTra
};

Resources