Mongoose : custom schema type - node.js

I followed this mongoose documentation on custom schema type, to create a "large string":
"use strict";
const mongoose = require('mongoose')
let STRING_LARGE = (key, options) => {
mongoose.SchemaType.call(this, key, options, 'STRING_LARGE');
};
STRING_LARGE.prototype = Object.create(mongoose.SchemaType.prototype);
STRING_LARGE.prototype.cast = function(val) {
let _val = String(val);
if(!/^[a-zA-Z0-9]{0,400}$/.test(_val)){
throw new Error('STRING_LARGE: ' + val + ' is not a valid STRING_LARGE');
}
return _val; };
module.exports = STRING_LARGE;
And I use it like this in a schema:
"use strict";
const mongoose = require('mongoose');
mongoose.Schema.Types.STRING_LARGE = require('./types/string_large')
const schema = new mongoose.Schema({
details: { type: STRING_LARGE, required: true },
link: { type: STRING_LARGE, required: true }
});
module.exports = schema;
But I get the error :
[path]\schemas[shema.js]:8
details: { type: STRING_LARGE, required: true },
ReferenceError: STRING_LARGE is not defined
at Object. ([path]\schemas[shema.js]:8:24)
...
-------------------------- UPDATE : WORKING CODE --------------------------
use "function ()" instead of "() =>"
"use strict";
const mongoose = require('mongoose')
function STRING_LARGE (key, options) {
mongoose.SchemaType.call(this, key, options, 'STRING_LARGE');
};
STRING_LARGE.prototype = Object.create(mongoose.SchemaType.prototype);
STRING_LARGE.prototype.cast = function(val) {
let _val = String(val);
if(!/^[a-zA-Z0-9]{0,400}$/.test(_val)){
throw new Error('STRING_LARGE: ' + val + ' is not a valid STRING_LARGE');
}
return _val; };
use "mongoose.Schema.Types.LARGE_STRING" instead of "LARGE_STRING"
module.exports = STRING_LARGE;
"use strict";
const mongoose = require('mongoose');
mongoose.Schema.Types.STRING_LARGE = require('./types/string_large')
const schema = new mongoose.Schema({
details: { type: mongoose.Schema.Types.STRING_LARGE, required: true },
link: { type: mongoose.Schema.Types.STRING_LARGE, required: true }
});
module.exports = schema;

You are assigning your type to mongoose.Schema.Types.STRING_LARGE and then use STRING_LARGE - that's where your ReferenceError is thrown. You have to use your type directly:
const schema = new mongoose.Schema({
details: { type: mongoose.Schema.Types.STRING_LARGE, required: true },
link: { type: mongoose.Schema.Types.STRING_LARGE, required: true }
});

Related

How can I give "type:richtext" to the schema inside the schema?

I have 2 files: service.admin.js and service.entity.js
Since I wanted to write the description in 3 languages, I created the DescriptionShema. but I want to make DescriptionShema "type:richtext". How can I do this in service.admin.js?
This is my code :
service.entity.js:
const mongoose = require('mongoose');
const DescriptionSchema = mongoose.Schema({
AZ: String,
ENG: String,
RU: String,
});
const ServiceSchema = new mongoose.Schema({
description: {
type: DescriptionSchema,
required: true,
}
});
const Service = mongoose.model('Service', ServiceSchema);
module.exports = { ServiceSchema, Service };
serivce.admin.js :
const AdminBro = require('admin-bro');
const { Service } = require('./service.entity');
/** #type {AdminBro.ResourceOptions} */
const options = {
properties: {
_id: {
isVisible: false,
}
}
};
module.exports = {
options,
resource: Service,
};
How can I change the type of DescriptionShema inside properties?

How to add data inside nested array in mongodb

I am using mongoose for database functionalities in my nodejs project.Below is my model.
Here is the POST request:
In MongoDb data is saving like this :
Here owers array is empty.
expense.js
const mongoose = require('mongoose');
const ExpenseSchema = new mongoose.Schema({
userid:{
type: String,
required: true
},
owers:[{
owerid:{
type: String
},
amt:{
type: Number
}
}],
name:{
type: String,
required: true
},
amount:{
type: Number,
require: true
}
});
const expense = mongoose.model('expense',ExpenseSchema);
module.exports = expense;
Whenever I am trying to insert something array is showing empty.Below is my code:
addExpense.js
const expense = require('../models/expense.js');
const addExpense = async (req,res) => {
const {name,amount,owerid,amt} = req.body;
console.log(name + " " + owerid);
const {userid} = req.params;
const expens = new expense({userid,name,amount});
try{
const data = await expens.save();
expens.owers.push({"owerid":owerid,"amt":amt});
res.send({"id":data._id});
}
catch(error){
res.send(error);
}
};
module.exports = {addExpense};
Someone let me know what I am doing wrong.
Try This
const {name,amount,owers} = req.body;
console.log(name + " " + owerid);
const {userid} = req.params;
const expens = new expense({userid,name,amount});
try{
const data = await expens.save();
//After you can push multiple data like that
JSON.parse(owers).map((value) => {
data.owers.push({
owerid: value.owerid,
amt: value.amt
})
})
data.save()
res.send({"id":data._id});
}
catch(error){
res.send(error);
}

Mongoose set empty array when update model

I have a problem with mongoose. I use MEAN stack.
I have an House Schema with some fields. When I update the house (with save method) mongoose update all fields but set an array in nested object empty. Why?
HOUSE SCHEMA
const mongoose = require('mongoose');
const posSchema = require('./pos');
const reviewSchema = require('./reviews');
const roomSchema = require('./rooms');
const contactSchema = require('./contacts');
const nearSchema = require('./nears');
const houseSchema = new mongoose.Schema({
title: { type: String, required: true },
description: { type: String, required: true },
shared: {
description: { type: String, required: true },
photos: { type: [String], required: true }
},
// OTHER FIELDS
}, { timestamps: true });
mongoose.model('House', houseSchema);
UPDATE FUNCTION
House.findById(body.house._id, "-__v", async (err, house) => {
if (err) { return res.status(400).json(err); }
else if (!house) { return res.status(400); }
house.title = body.house.title;
house.totalSize = parseInt(body.house.totalSize.toString());
house.bathrooms = parseInt(body.house.bathrooms.toString());
house.totalBeds = parseInt(body.house.totalBeds.toString());
house.description = body.house.description;
house.totalFreeBeds = parseInt(body.house.totalFreeBeds.toString());
house.minPrice = parseFloat(body.house.minPrice.toString()).toFixed(2);
house.type = body.house.type;
house.level = body.house.level;
house.top_floor = body.house.top_floor;
house.rooms = body.house.rooms;
house.checkboxes = body.house.checkboxes;
house.contacts = body.house.contacts;
house.pos = body.house.pos;
house.save(err => {
if (err) { console.log(err); return res.status(400).json(err); }
return res.status(200).json({ status: 200, remove: remove });
});
});
Before updating house.shared.photos is ["foo", "bar"]
After is [].
Why?
You are not setting the house.shared anywhere.
Try adding house.shared = body.house.shared before save call.

NodeJs Express API, trying to adding data/updating data to MongoDB but getting "Cannot read property '_id' of undefined"

I am trying to add a new collection, using the same ObjectId from the my users collection that was already created. But when I run the API, I get the following error Cannot read property '_id' of undefined
index.js
const express = require('express');
const authRoutes = require('./auth.routes');
const profileRoutes = require('./profile.routes');
const router = express.Router();
router.use('/auth', authRoutes);
router.use('/profile', profileRoutes);
module.exports = router;
profile.routes.js
const express = require('express');
const profileCtrl = require('../controllers/profile.controller');
const router = express.Router();
router
.route('/')
.post(profileCtrl.create)
.put(profileCtrl.update)
.get(profileCtrl.read)
.delete(profileCtrl.remove);
module.exports = router;
BaseCrudController.js
class BaseCrudController {
constructor(dataService, varName) {
if (!dataService) {
throw new Error('Data service not found', 500);
}
this.varName = varName;
this.dataService = dataService;
this.create = this.create.bind(this);
this.update = this.update.bind(this);
}
create(req, res, next) {
return this.dataService
.create(req.user, req.body)
.then((item) => res.json(item))
.catch(next);
}
update(req, res, next) {
return this.dataService
.update(req.user, req[this.varName], req.body)
.then((item) => res.json(item))
.catch(next);
}
BaseCrudService.js
const _ = require('lodash');
const mongoose = require('mongoose');
const APIError = require('../utils/api-error');
const BaseService = require('./BaseService');
class BaseCrudService extends BaseService {
constructor(
modelName,
safeFields = [],
adminFields = [],
userIdField = null,
populatedFields = [],
listPoluateField = ''
) {
super();
this.modelName = modelName;
this.safeFields = [...safeFields];
this.fields = [...safeFields];
this.adminFields = [...adminFields];
this.userIdField = userIdField;
this.populatedFields = [...populatedFields];
this.listPoluateField = listPoluateField;
this.model = mongoose.model(this.modelName);
this.create = this.create.bind(this);
this.update = this.update.bind(this);
}
_getFiedlNames(user) {
//maybe checking roles later
return [...this.safeFields];
}
create(user, data, extraData = {}) {
const Model = this.model;
const createData = {};
const fields = this._getFiedlNames(user);
if (this.userIdField) {
createData[this.userIdField] = user._id;
}
const item = new Model(
Object.assign(createData, _.pick(data, fields), extraData)
);
return item.save();
}
update(user, item, data) {
const fields = this._getFiedlNames(user);
const updateData = _.pick(data, fields);
Object.assign(item, updateData);
return item.save();
}
profile.model.js
const mongoose = require('mongoose');
const { Schema } = mongoose;
const profileSchema = new Schema({
user: { type: Schema.ObjectId, ref: 'User', required: true },
contactEmail: {
type: String,
required: true,
},
isEnabled: {
type: Boolean,
default: false,
},
about: {
type: String,
default: '',
},
portfolioUrl: {
type: String,
default: '',
},
jobTitle: {
type: String,
default: '',
},
resumeUrl: {
type: String,
default: '',
},
});
module.exports = mongoose.model('Profile', profileSchema);
Then when I try to test this in Postman, I get the following stack "TypeError: Cannot read property '_id' of undefined\n at ProfileService.create (/Users/tj/aydensoft/upwork-ABDS/portfolios/portfolios/services/BaseCrudService.js:46:43)\n at ProfileController.create (/Users/tj/aydensoft/upwork-ABDS/portfolios/portfolios/controllers/BaseCrudContoller.js:20:8)\n
Also the users collection automatically gets the _id:ObjectId("someNumber") when a user is added.
I tried many different ways but it ends up adding a totally different _id:ObjectId("someNumber") instead of the one matching _id:ObjectId("someNumber") in the users collection.

Mongoose statics Type Error : no such method

while calling static method of mongoose i am getting this error and i have searched for that error but still can't find relevant solution to resolve it
TypeError: Object function model(doc, fields, skipId) {
if (!(this instanceof model))
return new model(doc, fields, skipId);
Model.call(this, doc, fields, skipId);
} has no method 'returnEventType'
Model:
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var portalSchema = new Schema({
created: {
type: Date,
default: Date.now()
}
}),
eventType = new Schema({
ID: {
type: Schema.Types.ObjectId,
ref: 'docevents'
},
Accepted: {
type: Boolean,
default: 0
}
});
var Portal = mongoose.model('Portal', portalSchema),
EVENT = Portal.discriminator('EVENT', eventType);
portalSchema.statics.returnEventType = function(cb) {
cb(EVENT);
};
Controller:
exports.sendInvite = function(req,res) {
Portal.returnEventType(function(Event){
var EventObj = new Event({'ID': req.user._id});
EventObj.save(function(err,eventObj) {
console.log(eventObj);
});
}
You can't add static methods to your model after it's created, so move the definition of returnEventType before the call to model:
portalSchema.statics.returnEventType = function(cb) {
cb(EVENT);
};
var Portal = mongoose.model('Portal', portalSchema);

Resources