i'm new to nodeJS. am trying a use post request to get the information the user post but am getting an error: TypeError: Cannot read properties of undefined (reading 'title'). please what am i doing wrong here.
here's my code
const express = require("express")
const app = express()
const mongoose = require("mongoose")
const Schema = mongoose.Schema;
const BlogPost = new Schema({
title:{
type: String,
required: true
},
content: {
type: String,
required: true
},
body: {
type: String,
required: true
}
})
const Blog = mongoose.model("Blog", BlogPost)
module.exports = Blog;
app.post("/blogs", (req, res) => {
const blogs = new Blog({
title:req.body.title,
content: req.body.content,
body: req.body.body,
})
blogs.save()
.then(result => console.log(result))
.catch(err => console.log(err))
})
To make this code to workable condition for that add app.use(express.json())
As we are accepting http request body value from postman , so that it will parse our http request into json payload,
Hence we can access the body parameters value by req.body..
const express = require("express")
const app = express()
const mongoose = require("mongoose")
const Schema = mongoose.Schema;
// 2 json parsing
app.use(express.json())
//as my mongoose version is latest one so in that strictQuery is not supported
mongoose.set('strictQuery', false);
const BlogPost = new Schema({
title: {
type: String,
required: true
},
content: {
type: String,
required: true
},
body: {
type: String,
required: true
}
})
const Blog = mongoose.model("Blog", BlogPost)
module.exports = Blog;
//3. connection bridge between applicaion and mongoose
const connectionUrl = 'mongodb://127.0.0.1:27017'
mongoose.connect(connectionUrl, {
useNewUrlParser: true
},()=>{
console.log('Connected to MongoDB')
})
//Middleware
app.post("/blogs", (req, res) => {
//console.log(req.body.title+ " "+ req.body.content+ " "+ req.body.body );
const blogs = new Blog({
title: req.body.title,
content: req.body.content,
body: req.body.body,
})
blogs.save()
.then(result => console.log(result))
.catch(err => console.log(err))
})
// 1.listen
app.listen(3033, () => {
console.log("Server is running on port 3033")
});
/**
* use post request to get the information
* the user post but getting an error:
* TypeError: Cannot read properties of undefined (reading 'title').
*/
enter image description here
enter image description here
You may not get title from req.body.title that's why when you save this doc to mongodb it will throw this error.
For solution, you must check req.body.title before saving data into mongodb,
Otherwise, simply REMOVE required: true from schema
title:{
type: String,
required: true
},
Related
hey i am new here in nodejs and mongodb, i tyied to push comments on post in my social media project..
Here is my controller ,it shows error while pushing comments in mongodb
TypeError: Cannot read property 'push' of undefined
const Comment = require('../models/comment')
const Post = require('../models/post')
module.exports.create = function(req,res){
Post.findById(req.body.post, function(err ,post){
if(post){
Comment.create({
content: req.body.content,
post: req.body.post,
user: req.body._id
},function(err, comment){
if(err){console.log("error in pushing comment")}
post.comments.push(comment),
post.save()
res.redirect('/')
})
}
})
}
this is my comments schema
const mongoose = require('mongoose')
const commentSchema = new mongoose.Schema({
content: {
type: String,
required: true
},
//comments belongs to user
user : {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
},
post : {
type: mongoose.Schema.Types.ObjectId,
ref : 'Post'
}
},{
timestamps: true
})
const Comment = mongoose.model('Comment' , commentSchema)
module.exports = Comment
I recommend that you use Promises instead of callback functions. It will make your code way more readable. Monogoose findOneAndUpdate could be handy here.
As for the error, you should make a console.log(post.comments) to see the value for yourself.
We should see the model of Post. It should contain an array of Comments
const mongoose = require('mongoose')
const Comment = require('./comment.model.js') // Change the path
const postSchema = new mongoose.Schema({
// comments belongs to post
comments : {
type: [Comment]
},
// Other attributes here
},{
timestamps: true
})
const Post = mongoose.model('Post' , postSchema)
module.exports = Post
You'll end up with something like this:
const Comment = require('../models/comment')
const Post = require('../models/post')
module.exports.create = function (req, res) {
Post.findById(req.body.post).then((post) => {
if (post) {
Comment.create({
content: req.body.content,
post: req.body.post,
user: req.body._id
}).then((comment) => {
Post.findOneAndUpdate(
{ _id: req.body.post },
{ $push: { comments: comment } }
).then(() => {
res.redirect('/')
}).catch((error) => console.log(error))
})
}
}).catch((error) => console.log(error))
}
I'm pretty new to node and mongoose, still learning a lot. Basically I am trying to create a forum page. I have a forumpost schema and I have recently added in a new field that I would like to show which user posted it. I have read other questions on this online and I was able to follow the code on there however mine is still not working. When i check my data in atlas it is still missing the new 'submitted by' field that I added. I have already deleted the 'collection' and have started over but it is still missing. Any help would be appreciated. Heres my models below as well as a screencap of how the data is being posted to the db.
**Post Form Schema**
const mongoose = require('mongoose');
const PostSchema = new mongoose.Schema({
title: {
type: String,
required: true
},
body: {
type: String,
required: true,
},
date: {
type: Date,
default: Date.now,
required: true,
},
submittedBy: { *(this is where I would like to get the user who submitted the form)*
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
},
extraInfo: {
type: String,
default: 'Other info goes here',
}
})
const Post = mongoose.model('Post', PostSchema);
module.exports = Post;
**Users Form Schema**
const mongoose = require('mongoose');
const UserSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
}
});
const User = mongoose.model('User', UserSchema);
module.exports = User;
EDIT: heres my newpost route
const express = require('express');
const Post = require('../models/post');
const router = express.Router();
const {ensureAuthenticated} = require("../config/auth.js");
router.get('/', ensureAuthenticated, (req, res) => {
res.render('newPost')
})
router.post('/', ensureAuthenticated, (req, res) => {
const post = new Post(req.body);
console.log(req.body)
post.save()
.then((result) => {
res.redirect('/dashboard')
})
.catch((err) => {
console.log(err)
})
})
module.exports = router;
If I'm not mistaken, you validate if is authenticated with the "ensureAuthenticated" middleware (the user ID should be there) but when creating the "Post" you only do it with the body data.
It is something like this ( you should replace "userId" with your property name):
const post = new Post({ ...req.body, submittedBy: userId })
Hello I want to be able to pass a user into a get request to see what items they have posted.
Here is the GET request
// #route GET with NAME
// #desc GET All ITEMS WITH NAME
// #access private
router.get('/:user', (req, res) => {
Item.findBy(req.params.user)
.sort({ date: -1})
.then(items => res.json(items))
});
Then I want to be able to pass it through the actions file.
export const getItems = () => dispatch => {
dispatch(setItemsLoading());
axios.get(`/api/items/`).then(res =>
dispatch({
type: GET_ITEMS,
payload: res.data
})
)
.catch(err =>
dispatch(returnErrors(err.response.data, err.response.status))
);
}
Here is the item modal if anyone was wondering
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
//Create Schema
const ItemSchema = new Schema({
name:{
type: String,
required: true
},
user:{
type: String,
required: true
},
date:{
type: Date,
default: Date.now
}
});
module.exports = Item = mongoose.model('item', ItemSchema);
The expected results of this would be
http://localhost:3000/{username}
Product list
"name":"Item name"
"date": "mm/dd/yy"
I am also new to mongoDB/Json. I am coming from using SQL.
In this case I would use req.query.user and the url would be http://localhost:3000/?username.
Then in router.get method pull the correct db data from mongoDB and res.send data to client.
I think it's not populating categories couse when i try log 'category' in console i get
"ReferenceError: category is not defined". For me it is like in docs but as we see it's not. Is anyone can tell me what is wrong??
//model/Category.js
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const CatSchema = new Schema({
title: {
type: String,
required: true
},
body: {
type: String,
required: true
}
});
mongoose.model("categories", CatSchema, "categories");
model/Story.js
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const StorySchema = new Schema({
title: {
type: String,
required: true
},
body: {
type: String,
required: true
},
category: {
type: Schema.Types.ObjectId,
ref: "categories"
}
});
mongoose.model("stories", StorySchema, "stories");
routes/stories.js
const express = require('express');
const router = express.Router();
const mongoose = require('mongoose');
const Category = mongoose.model('categories');
const Story = mongoose.model('stories');
router.get('/add', (req, res) => {
Story.find()
.populate('category', 'title')
.then(stories => {
res.render('stories/add', {
stories: stories
});
});
});
Query.prototype.populate() returns a Query object on which you need to run .exec(), try this:
Story.find({})
.populate('category', 'title')
.exec()
.then(stories => {
res.render('stories/add', {
stories: stories
});
});
It was problem with that how I want to use it. Code is working
I have a node-express application that connects to MongoDB using the Mongoose library.
But I'm having problems getting my custom Mongoose plugins to bring changes to the documents before they are saved to the database.
Here is how I define my plugin:
const requestContext = require('request-context');
module.exports = (schema, options) => {
schema.pre('save', next => {
const author = requestContext.get('request').author;
this._createdBy = author.sub;
this._owner = author.sub;
this._groupOwner = author.group;
next();
});
schema.pre('findOneAndUpdate', next => {
const author = requestContext.get('request').author;
this._lastEditAt = Date.now();
this._lastEditBy = author.sub;
next();
});
}
Then I add it to the schema like this:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const trace = require('../plugins/trace');
const PostSchema = new Schema({
title: String,
Text: String,
category: String,
_createdAt: {
type: Date,
default: Date.now
},
_lastEditAt: Date,
_createdBy: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
},
_lastEditBy: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
},
_owner: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
},_groupOwner: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Group'
}
});
PostSchema.plugin(trace);
exports.schema = PostSchema;
exports.model = mongoose.model('Post', PostSchema);
In my Express controller:
const router = require('express').Router();
const Post = require('../model/post').model;
router.post('/', (req, res) => {
const post = new Post(req.body);
post.save()
.then(() => res.json(post))
.catch(err => res.status(400).json(err));
});
router.put('/', (req, res) => {
Post.findByIdAndUpdate(req.body._id, req.body, {new: true})
.then(post => res.json(post))
.catch(err => res.status(400).json(err));
});
The pre hooks defined by the plugin are triggered but the changes they bring are never persisted to the database. Is this a bug in Mongoose plugin system.
I have tried with Mongoose#4.13.9 and Mongoose#5.3.3 but none works.
I was struggling with this issue during all the week-end.
Luckily I have found the origin of the problem.
First: I was using arrow functions for my hook methods, which changes the context of the this keyword.
So I had to define my hook functions using the old es5 function syntax as follows:
const requestContext = require('request-context');
module.exports = (schema, options) => {
schema.pre('save', function(next) {
const author = requestContext.get('request').author;
this._createdBy = author.sub;
this._owner = author.sub;
this._groupOwner = author.group;
next();
});
}