MissingSchemaError: Schema hasn't been registered for model images - node.js

I keep getting the same error that my imageSchema hasn't been registered for ImageModel when I try to populate the posts from UserModel. But I can't figure out what's the issue. I checked the image Schema file and I don't see anything wrong. Or am I missing something else?
User model
const userSchema = new mongoose.Schema(
{
name: {
type: String,
required: true
},
username: {
type: String,
required: true
},
email: {
type: String,
required: true
},
password: {
type: String,
min: 6,
max: 30
},
created: {
type: Date,
required: true,
default: Date.now
},
},
{
timestamps: true,
toJSON: {
virtuals: true
}
},
);
userSchema.virtual("posts", {
ref: "ImageModel",
foreignField: 'userId',
localField: '_id'
});
module.exports = mongoose.model('users', userSchema);
Image model
const imageSchema = new mongoose.Schema({
caption: {
type: String,
},
timeCreated: {
type: Date,
default: () => Date.now(),
},
img: {
type: String,
default: 'placeholder.jpg',
},
});
module.exports = mongoose.model("imagesPosts", imageSchema);
model routes
const UserModel = require("../models/User");
const ImageModel = require("../models/Image");
This is the code I'm working on to populate the posts from the User model, but I'm not sure if I'm doing it correctly or not.
const userId = req.user.id;
try {
const result = await UserModel.findById(userId).populate("posts");
console.log("\n\nPopulate result: " + result + "\n\n");
} catch (err) {
console.log(err);
res.status(500).send("Something went wrong, check logs");
}
**Desired output: **
{
"_id": "5e3a885ec511414a3c37a78c",
"username": "Johm",
"email": "john#head.dev",
"password": "123123",
"__v": 0,
"posts": [
{
"_id": "5e3a88e2c511414a3c37a78d",
"caption": "caption one",
"img": "1661309774553spaghetti.jpg",
"userId": "5e3a885ec511414a3c37a78c",
"created": "2020-02-05T09:20:49.754Z",
"__v": 0
},
{
"_id": "5e3a88f1c511414a3c37a78e",
"caption": "caption two",
"img": "1661309774553spaghetti.jpg",
"userId": "5e3a885ec511414a3c37a78c",
"created": "2020-02-05T09:20:49.754Z",
"__v": 0
}
],
}

Declare your posts field as a ref in userSchema:
const userSchema = new mongoose.Schema(
{
posts: [
{
type: mongoose.Schema.Types.ObjectId,
ref: 'imagesPosts',
},
],
...
);
You should be able to populate it with:
await UserModel.findById(userId).populate("posts").exec();

Related

How to get model data from nested object

little bit stuck with mongoose. I want to get all users projects where he's added. Tried few options, but in all of them I receive an empty array. So the main question is it possible somehow to find all project by filtering/finding the Project model?
This is how looks my default response to understand what I'm looking for:
{
"_id": "61a8bc4e8e24f10ac7a7288d",
"name": "Random project",
"description": "Random project desc",
"maxWorkingEmployees": 5,
"status": "Paused",
"createdBy": {
"_id": "61a66578f2dabf7555bcf4ab",
"email": "Henrikas#furniture1.eu",
"role": "Owner"
},
"currentlyWorkingEmployees": [
{
"username": "Ema",
"role": "Employee",
"_id": "61a8e0423140ecce769dc971"
}
],
"createdAt": "2021-12-02T12:30:06.461Z",
"updatedAt": "2021-12-02T15:11:51.361Z",
"__v": 0
}
Project model:
const mongoose = require('mongoose');
const SingleUserSchema = new mongoose.Schema({
username: {
type: String,
required: true,
},
role: {
type: String,
required: true,
},
});
const ProjectSchema = new mongoose.Schema(
{
name: {
type: String,
required: [true, 'Provide project name'],
minlength: 5,
},
description: {
type: String,
required: [true, 'Provide description about the project'],
},
maxWorkingEmployees: {
type: Number,
required: [
true,
'Provide maximum number of employees working on this project',
],
},
currentlyWorkingEmployees: [SingleUserSchema],
status: {
type: String,
enum: ['Pending', 'In progress', 'Paused', 'Delayed', 'Completed'],
default: 'Pending',
},
createdBy: {
type: mongoose.Schema.ObjectId,
ref: 'User',
required: true,
},
},
{ timestamps: true }
);
module.exports = mongoose.model('Project', ProjectSchema);
Here's my controller and my first try:
const getMyProjects = async (req, res) => {
const userId = req.user.userId;
const projects = await Project.find({
currentlyWorkingEmployees: { _id: userId },
});
res.json({projects});
};
Second shot after reading some articles
const getMyProjects = async (req, res) => {
const userId = req.user.userId;
const projects = await Project.aggregate([
{
$match: {
currentlyWorkingEmployees: { _id: userId },
},
},
]);
};
As I said in the comment you can do it accessing to the internal object of the schema with an string accessing to it child object.
Project.find({'currentlyWorkingEmployees._id': userId})

Problem with the relationship in express/mongoose

Im creating a document named 'Sells', each sell has properties such as date, name, total, the id of the user who created it ect. and I have another document named 'Sell_details' where I store the details of each sell with their sell _id. So how do i retrieve all the sells i have in the database with an array of the details which that sell has? I've tried to do it but it doesn't retrieve all the details and among other problems. Here's what i have.
this is the sell model
const mongoose = require('mongoose');
const validator = require('validator');
const uniqueValidator = require('mongoose-unique-validator');
const ventaSchema = new mongoose.Schema({
usuarioId: {
type: mongoose.Schema.Types.ObjectId,
required: true
},
clienteId: {
type: mongoose.Schema.Types.ObjectId,
required: true
},
tipo_comprobante: {
type: String,
required: true
},
num_comprobante: {
type: Number,
required: true
},
serie_comprobante: {
type: Number,
required: true
},
fecha: {
type: Date,
default: Date.now()
},
impuesto: {
type: Number,
required: true
},
total: {
type: Number,
required: true
},
estado: {
type: String,
default: 'Activo'
},
owner: {
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: 'User'
},
ventas: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Detalle_Venta'
},
detalles: {
type: Array
}
},{ toJSON: { virtuals: true } });
ventaSchema.plugin(uniqueValidator, { message: 'Expected {PATH} to be unique' });
const Venta = mongoose.model('Venta', ventaSchema);
module.exports = Venta;
his is the sell router:
router.get('/ventas', auth, async(req, res) => {
try {
await req.user.populate({
path: 'ventas',
options: {
limit: req.query.limit
}
}).execPopulate();
req.user.ventas.forEach(element => {
const detalles = Detalle_Venta.find({ventaId: element._id});
detalles.then(el => {
el.forEach(detalle => {
if (element.detalles.length > 1) {
element.detalles.forEach(el => {
const isAdded = el._id === detalle._id;
if (isAdded) {
element.detalles.push(detalle);
}
})
} else {
element.detalles.push(detalle);
}
});
});
element.save();
});
res.send(req.user.ventas);
} catch (error) {
res.status(400).send(error);
}
});
and this is the output from postman:
[
{
"fecha": "2020-06-22T18:16:44.175Z",
"estado": "Activo",
"detalles": [
{
"_id": "5ef0fa4e49de0641c46eca0b",
"idArticulo": "5ee825bfb3da101df49822ae",
"cantidad": 30,
"precio": 2,
"descuento": 0,
"ventaId": "5ef0fa4e49de0641c46eca0a",
"__v": 0
},
{
"_id": "5ef0fa4e49de0641c46eca0b",
"idArticulo": "5ee825bfb3da101df49822ae",
"cantidad": 30,
"precio": 2,
"descuento": 0,
"ventaId": "5ef0fa4e49de0641c46eca0a",
"__v": 0
}
],
"_id": "5ef0fa4e49de0641c46eca0a",
"usuarioId": "5ee3b6b50376d7143c476834",
"clienteId": "5ee6b115e43839274cc50ddb",
"tipo_comprobante": "RNC",
"num_comprobante": 1000000,
"serie_comprobante": 20001,
"impuesto": 18,
"total": 10500,
"owner": "5ef0e64083f8c815cc67cd7c",
"__v": 2,
"id": "5ef0fa4e49de0641c46eca0a"
},
{
"fecha": "2020-06-22T18:16:44.175Z",
"estado": "Activo",
"detalles": [
{
"_id": "5ef0fa5a49de0641c46eca0d",
"idArticulo": "5ee825bfb3da101df49822ae",
"cantidad": 30,
"precio": 2,
"descuento": 0,
"ventaId": "5ef0fa5a49de0641c46eca0c",
"__v": 0
},
{
"_id": "5ef0fa5a49de0641c46eca0e",
"idArticulo": "5ee825bfb3da101df49822ae",
"cantidad": 303,
"precio": 2,
"descuento": 0,
"ventaId": "5ef0fa5a49de0641c46eca0c",
"__v": 0
}
],
"_id": "5ef0fa5a49de0641c46eca0c",
"usuarioId": "5ee3b6b50376d7143c476834",
"clienteId": "5ee6b115e43839274cc50ddb",
"tipo_comprobante": "RNC",
"num_comprobante": 1000000,
"serie_comprobante": 20001,
"impuesto": 18,
"total": 10500,
"owner": "5ef0e64083f8c815cc67cd7c",
"__v": 1,
"id": "5ef0fa5a49de0641c46eca0c"
}
]
Before you say i did it, the first array of the 'detalles' array (which stores the sell details of that sell), i added one sell detail and i'm getting two, and the second array of the other sell, i'm getting two sell details but i added 3 and if i add 4 i'm only getting 2 and i don't know why. is there a way to fix it and another best way to do it ?
mongoose has a powerful aggregation operator called populate which you have used.
You should use type ObjectId to the property sell details.
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const personSchema = Schema({
_id: Schema.Types.ObjectId,
name: String,
age: Number,
stories: [{ type: Schema.Types.ObjectId, ref: 'Story' }]
});
const storySchema = Schema({
author: { type: Schema.Types.ObjectId, ref: 'Person' },
title: String,
fans: [{ type: Schema.Types.ObjectId, ref: 'Person' }]
});
Then you create the author and story linking them up
const author = new Person({
_id: new mongoose.Types.ObjectId(),
name: 'Ian Fleming',
age: 50
});
author.save(function (err) {
if (err) return handleError(err);
const story1 = new Story({
title: 'Casino Royale',
author: author._id // assign the _id from the person
});
story1.save(function (err) {
if (err) return handleError(err);
// that's it!
});
});
You can thereafter populate
Story.
findOne({ title: 'Casino Royale' }).
populate('author').
exec(function (err, story) {
if (err) return handleError(err);
console.log('The author is %s', story.author.name);
// prints "The author is Ian Fleming"
});
This will ensure you don't get an entry twice..

I am trying to populate the **task_item** you can see below but I am not getting the result. Nodejs, Expressjs and MongoDb

I am trying to populate the task_item you can see below but I am not getting the result.
{
"msg": "User not exists",
"cart": {
"_id": "5ec0c28cf494113aa06c99d9",
"task_items": [
{
"quantity": 1,
"_id": "5ec0c28cf494113aa06c99da",
**"task_item": "5ebe499d7e657d322c39345f"**
},
{
"quantity": 1,
"_id": "5ec0d018ecc2411cf40bceae",
**"task_item": "5ebe499d7e657d322c39345f"**
},
{
"quantity": 1,
"_id": "5ec0d4abfac25246689d15a7",
**"task_item": "5ec0d4a2fac25246689d15a6"**
}
],
"crreated": "2020-05-17T04:50:20.869Z",
"user": {
"_id": "5ebe4d5d440ab504c8a0d128",
"name": "Ajit",
"phone": "9668854799",
"avatar": "//www.gravatar.com/avatar/20c3d59b7049c9ad85cd33e2ebd3151c?s=200&r=pg&d=mm",
"password": "$2a$10$FdH7QzoqOHnVoLbbm9GaUOLaJbTTqPWzFWeFACkea2NWlrJrFxZ5a",
"createdAt": "2020-05-15T08:05:49.418Z",
"__v": 0
},
"__v": 2
}
}
Below is the Cart.js Model
const monngose = require('mongoose');
const Schema = monngose.Schema;
const CartSchema = new Schema({
user: {
type: Schema.Types.ObjectId,
ref: 'user'
},
task_items: [{
task_item: {type:Schema.Types.ObjectId, ref: 'SubTaskCategoryItem'},
quantity: { type: Number, default: 1 }
}],
totalPrice: {
type: Number
},
item: {
type: Schema.Types.ObjectId,
ref: 'SubTaskCategoryItem'
},
crreated: {
type: Date,
default: Date.now
}
});
module.exports = monngose.model('Cart', CartSchema);
SubCategoryItem.js - This is the item model
const mongoose = require('mongoose');
const SubTaskItemSchema = new mongoose.Schema({
subtaskItemName: {
type: String,
required: true,
unique: true,
trim: true
},
subtaskItemImage: {
type: String
},
subtaskItemTime: {
type: String
},
description: {
type: String,
trim: true
},
subtaskItemPrice: {
type: String
},
subtaskItemStatus: {
type: Boolean,
default: true
},
subtask: {
type: mongoose.Schema.ObjectId,
ref: 'SubTask',
required: true
},
createdAT: {
type: Date,
default: Date.now
}
})
module.exports = mongoose.model("SubTaskCategoryItem", SubTaskItemSchema);
Here I am trying to populate - cart.js router
const express = require('express');
const Cart = require('../../models/admin/Cart');
const checkJwt = require('../../middleware/admin/user_auth');
const TaskItem = require('../../models/admin/SubTaskCategoryItem');
const router = express.Router();
router.post('/add_cart', checkJwt, (req, res, next) => {
const product_id = req.query.productId;
const quantity = req.query.quantity;
const user = req.user.id;
router.get('/get_cart', checkJwt, (req, res, next) => {
Cart.findOne({ user: req.user.id })
.populate({
path: 'user'
})
.populate({
path: 'item'
})
.exec((err, cart) => {
res.json({
msg: 'User not exists',
cart: cart
});
})
})
module.exports = router;
I am trying to populate the task_item but I am not able to do. If anyone knows please see this code.

get data into schema by id in mongoose

i have two schema i would like to get some info from another schema for example (firstName, lastName) from the userSchema by id that i would provide when adding new comment on the CommentsSchema
const CommentsSchema = new mongoose.Schema({
userId: {
type: String,
required: true
},
commentText: {
type: String,
required: true
},
time: {
type: Date,
default: Date.now
}
});
const UserSchema = new mongoose.Schema({
userName: {
type: String,
required: true
},
firstName: {
type: String,
required: true
},
lastName: {
type: String,
required: true
}
});
You can use mongoose populate to get data from a referenced collection.
First you need to change comments schema to set up a reference to the User model.
You may need to change ref value, if you used a different user model name when you applied mongoose.model("User", UserSchema).
const CommentsSchema = new mongoose.Schema({
userId: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
required: true
},
commentText: {
type: String,
required: true
},
time: {
type: Date,
default: Date.now
}
});
Let's say you have this user in users collection:
{
"_id": "5e312d5cab2e5028b8865be3",
"userName": "Mongoose",
"firstName": "Buk",
"lastName": "Lau",
"__v": 0
}
And this comment from this user:
{
"_id": "5e312d9cab2e5028b8865be4",
"userId": "5e312d5cab2e5028b8865be3",
"commentText": "this is a comment",
"time": "2020-01-29T07:00:44.126Z",
"__v": 0
}
Now you can access the user info from comment like this:
router.get("/comments/:id", async (req, res) => {
const result = await Comment.findById(req.params.id).populate("userId");
res.send(result);
});
The result will be like this:
{
"_id": "5e312d9cab2e5028b8865be4",
"userId": {
"_id": "5e312d5cab2e5028b8865be3",
"userName": "Mongoose",
"firstName": "Buk",
"lastName": "Lau",
"__v": 0
},
"commentText": "this is a comment",
"time": "2020-01-29T07:00:44.126Z",
"__v": 0
}

Populate() Mongoose is not returning joined data

Well, I´am trying to retrieve Name and Lastname from user who created the document but it´s not working, it still returning Mongo´s Id
This is my areas model
var mongo = require('mongoose'),
validator = require('mongoose-unique-validator'),
Schema = mongo.Schema
var model = new Schema({
NAME: { type: String, required: true, unique: true, max: 50, min: 3 },
STATUS: { type: String, default: 'active' },
ADDED_BY: { type: Schema.Types.ObjectId, ref: 'users' },
ADDED_DATE: { type: Date, default: Date.now }
}, {collection :'areas'})
model.plugin( validator, { message: 'The {PATH} is not valid or duplicated' } )
module.exports = mongo.model('Area', model )
This is the user model
var mongo = require('mongoose'),
validator = require('mongoose-unique-validator'),
Schema = mongo.Schema
var userSchema = new Schema({
PERSONAL_DATA: {
NAME: { type: String, required: [ true, 'The name is necessary' ], max: 50 },
LAST_NAME: { type: String, required: [ true, 'the lastname is necessary' ], max: 100 },
PHOTO: { type: String, max: 100 },
BIRTHDAY: { type: Date },
MARITIAL_STATUS: { type: Schema.Types.ObjectId, ref: 'maritial_statuses' },
GENDER: { type: String, max: 1 },
EMAIL: { type: String, required: true },
},
COMPANY_DATA: {
JOB: { type: Schema.Types.ObjectId, ref: 'jobs' },
AREA: { type: Schema.Types.ObjectId, ref: 'areas' },
ROLE: { type: Schema.Types.ObjectId, ref: 'roles' },
BOSS: { type: Schema.Types.ObjectId, ref: 'users' },
}
}, { collection: 'users' } )
model.plugin( validator, { message: 'The {PATH} is not valid or duplicated' } )
module.exports = mongo.model('User', userSchema )
And this is my areas route
var express = require('express'),
model = require('../../models/catalogs/areas'),
app = express()
app.get('/:from', (req, res) => {
var from = parseInt( req.params.from )
model.find()
.sort('NAME').populate({ path: 'users', select: 'NAME LAST_NAME'})
.limit(10).skip(from)
.exec((error, data) => {
if (error) {
return res.status(500).json({
success: false,
error
})
}
res.status(200).json({
success: true,
data
})
})
})
module.exports = app
The response is
{
"success": true,
"data": [
{
"STATUS": "active",
"_id": "5c547f4adadf433914f72c8c",
"NAME": "Contabilidad y Finanzas",
"ADDED_BY": "5c4f562deec6f4defeea759b",
"ADDED_DATE": "2019-02-01T17:18:02.680Z",
"__v": 0
},
{
"STATUS": "active",
"_id": "5c547f3edadf433914f72c8b",
"NAME": "Tecnologías",
"ADDED_BY": "5c4f562deec6f4defeea759b",
"ADDED_DATE": "2019-02-01T17:17:50.579Z",
"__v": 0
}
]
}
As you seen, ADDED_BY is a field joined to Users and I want to retrieve that information. I don´t know what is wrong with my code.

Resources