My code is as follows and gets me "message": "Product is not a constructor" using postman.
Router seems to be properly configured but now I don't know what is the issue.
File product constructor is placed at the right direction. When running node server I get no errors in terminal.
product constructor
const mongoose = require('mongoose');
const productSchema = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
name: String,
price: Number
});
module.export = mongoose.model('Product', productSchema);
Router for POSTS
const mongoose = require('mongoose');
const Product = require('../models/product'); //import schema, product constructor
//POSTs to products
router.post('/', (req,res,next) => {
//ObjectId method to add new ID
const product = new Product({
_id: new mongoose.Types.ObjectId(),
name: req.body.name,
price: req.body.price
});
//mongoose method to save data
product
.save()
.then(result => {
console.log(result);
})
.catch(err => console.log(err));
res.status(201).json({
message: 'sending POSTs to /products',
createdProduct: product
});
});
It should be module.exports (doc), not module.export:
module.exports = mongoose.model('Product', productSchema);
Right now your module essentially exports a default value (an empty object).
As a sidenote, Schema is expected to be used as a constructor. While the function itself is written the way it'll recall itself with proper syntax if used without new:
if (!(this instanceof Schema)) {
return new Schema(obj, options);
}
... you can both avoid this (albeit miniscule) loss of performance and, what's more important, show the actual intent clearly:
const productSchema = new mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
name: String,
price: Number
});
Probably you should create instance of Schema
const productSchema = /*(this --->)*/ new mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
name: String,
price: Number
});
Related
Mongoose gives validation error even if i give the correct create arguments. Checked, function just works one time & variables are not null.
Note: There are several models imported to file with same architecture of Payment Model.
await payment.create({
userId: user._id,
paymentDetails: session
})
Payment Model:
const mongoose = require('mongoose')
const { Schema } = mongoose
mongoose.connect('<REDACTED>')
const Payments = new Schema({
id: String,
userId: { type: String, required: true },
paymentDetails: {type: Object, required: true},
})
module.exports =
mongoose.models.Payments || mongoose.model('Payments', Payments)
I'm totally new to mongoDB, just coming from MySQL, so I'm trying to add a new document to a mongo database in Node.js, I have the code working except when I have to include a custom object.
Here's my code:
router.post('/', async (req, res) => {
const book= new Book({
title: req.body.book.title,
year_published: req.body.book.year_published,
author: req.body.author // ==> here is the problem without it works fine (comes the full author via body parameter)
});
try {
const savedBook = await book.save();
res.json({
insertedBook: savedBook
});
} catch (err) {
//console.log("Error:" + err);
res.json({error: err});
}
});
The book and author models (simplified):
// ======= AUTHORS ================ //
var mongoose = require('mongoose');
var mongoosePaginate = require('mongoose-paginate-v2');
const schema = new mongoose.Schema({
name: {
type: String,
required:true
},
place_birth: {
type: String,
required:true},
});
schema.plugin(mongoosePaginate);
const Authors = mongoose.model('Authors',schema);
module.exports = Authors;
// ======= BOOKS ================ //
var mongoose = require('mongoose');
var mongoosePaginate = require('mongoose-paginate-v2');
var ObjectId = mongoose.Schema.Types.ObjectId;
const schema = new mongoose.Schema({
title: {
type: String,
required:true
},
year_published: {
type: String,
required:true},
author: [{
type: ObjectId,
ref: 'Authors',
required:false
}],
});
schema.plugin(mongoosePaginate);
const Books = mongoose.model('Books',schema);
module.exports = Books;
Data posting:
{
"book": {
"title": "Entrada con cuernos",
"year_published": "2020",
},
"author": {
"name": "Marcus",
"place_birth": "Moscow",
}
}
What's the proper way to insert a book document?
Thanks
When creating a new Book, Book.author should be a mongoose document, meaning the Author should exist in the mongoDB already.
You need to first save the Author in the DB, then pass it in Boot.author with it's Author._id property set
P.S.: Use singular words when describing your collections:
const Authors = mongoose.model('Authors',schema);
const Authors = mongoose.model('Author',schema); // recommended
mongoose will take care of the plural naming
The first argument is the singular name of the collection your model is for. Mongoose automatically looks for the plural, lowercased version of your model name
I am trying to import a schema file(order.js) inside user.js from "models" folder.
My application gets crashed after saving user.js, it throws an error as follows,
"TypeError: Invalid value for schema path product.type, got value "undefined""
In user.js, I have imported order.js as follows,
const User = require("../models/user");
const Order = require("../models/order"); //Throws error on this line.
But when I comment require("../models/order") line, app starts to perform well.
This is my multiple Schema file (order.js):
const mongoose = require("mongoose");
const { Objectid } = mongoose.Schema;
const productCartSchema = new mongoose.Schema({
product: {
type: Objectid,
ref: "Product",
},
name: String,
count: Number,
price: Number,
});
const ProductCart = mongoose.model("ProductCart", productCartSchema);
const orderSchema = new mongoose.Schema(
{
products: [productCartSchema],
transactionid: {},
address: String,
amount: { type: Number },
updated: Date,
user: {
type: Objectid,
ref: "User",
},
},
{ timestamps: true }
);
const Order = mongoose.model("Order", orderSchema);
module.exports = { Order, ProductCart };
I have found a solution on this issue.
The ObjectId in my order.js is not defined. I just replaced it with mongoose.Schema.Types.ObjectId
This solved my issue.
I'm working on a project that uses a node/express API and Mongo for storage. I have a function that tries to retrieve data from the storage using the code in the screenshot below. My understanding of async/await is that at the point of await, code execution will pause and proceed when the promise is resolved.
However, the data returned by the function (in the screenshot) is always null, although, the record is there in the db. [The slug is also passed correctly.]
I am starting to believe I am missing something regarding the concept of async/await.
Could anyone please assist me with this?
Am I doing something wrong here?
The calling function is as follows:
async create(req, res, next) {
debug(chalk.blue(`*** Create RSVP`));
console.log(req.body.event); //event is defined and matches db
const event = await Event.findBySlug(req.body.event);
console.log(event); // logs null here
}
Called function:
async function findBySlug(slug) {
return await Model.findOne({ slug: slug })
.populate('user')
.populate('category')
.exec();
}
I have run your code, findBySlug should be working fine. below is sample code for you.
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const ObjectId = Schema.ObjectId;
mongoose.Promise = global.Promise;
mongoose.connect('mongodb://localhost:27017/database-name', {useNewUrlParser: true});
const UserSchema = new mongoose.Schema({
username: String
})
const CategorySchema = new mongoose.Schema({
name: String
})
const PostSchema = new mongoose.Schema({
content: String,
author: {
type: ObjectId,
ref: 'User'
},
category: {
type: ObjectId,
ref: 'Category'
}
})
const Post = mongoose.model('Post', PostSchema, 'posts');
const User = mongoose.model('User', UserSchema, 'users');
const Category = mongoose.model('Category', CategorySchema, 'categories');
async function findBySlug() {
return await Post.findOne({ content: "content name" })
.populate('author')
.populate('category')
.exec();
}
(async function run() {
const event = await findBySlug();
console.log(event); // logs not null here
}())
updating your findBySlug method like this will be enough.
function findBySlug(slug) {
return Model.findOne({ slug: slug })
.populate('user')
.populate('category')
.exec();
}
I'm new to Express/Mongoose and backend development. I am attempting to use a Mongoose subdocument in my Schema and POST data from a form to an MLab database.
I am successfully POSTing to the database when only using the parent Schema, but when I attempt to also POST data from the subdocument I am getting an undefined error. How do I properly POST data from a subdocument?
Here is my Schema:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const bookSchema = new Schema({
bookTitle: {
type: String,
required: true
},
author: {
type: String,
required: true
},
genre: {
type: String
}
});
const userSchema = new Schema({
name: String,
username: String,
githubID: String,
profileUrl: String,
avatar: String,
// I've tried this with bookSchema inside array brackets and also
//without brackets, neither works
books: [bookSchema]
});
const User = mongoose.model('user', userSchema);
module.exports = User;
Here is my route where I attempt to POST to the database:
router.post('/', urlencodedParser, (req, res) => {
console.log(req.body);
const newUser = new User({
name: req.body.name,
username: req.body.username,
githubID: req.body.githubID,
profileUrl: req.body.profileUrl,
avatar: req.body.avatar,
books: {
// All of these nested objects in the subdocument are undefined.
//How do I properly access the subdocument objects?
bookTitle: req.body.books.bookTitle,
author: req.body.books.author,
genre: req.body.books.genre
}
});
newUser.save()
.then(data => {
res.json(data)
})
.catch(err => {
res.send("Error posting to DB")
});
});
Figured it out. I wasn't properly accessing the values using dot notation.
books: {
// All of these nested objects in the subdocument are undefined.
//How do I properly access the subdocument objects?
bookTitle: req.body.books.bookTitle,
author: req.body.books.author,
genre: req.body.books.genre
}
No need to access .books inside of the books object. req.body.books.bookTitle should be req.body.bookTitle and so forth. Leaving this post up in case it helps someone else.