I am trying to create an api endpoint in nodejs to insert data in mongodb. I have got two mongoose schemas which are related to each other that`s why i am relating these two schemas like below:
Posts schema:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const PostSchema = mongoose.Schema({
title: { type: String, trim: true, required: true},
description: { type:String, required: true },
created_at: { type: Date, default: Date.now },
author: {type: Schema.ObjectId, ref: 'Author', required: true},
});
const Post = module.exports = mongoose.model('Post', PostSchema);
Authors Schema:
const mongoose = require('mongoose');
const AuthorSchema = mongoose.Schema({
fullname: { type: String, trim: true, required: true},
address: { type: String, required: true },
phone: { type: Number, required: true },
email: { type: String, required: true },
created_at: { type: Date, default: Date.now }
});
const Author = module.exports = mongoose.model('Author', AuthorSchema);
Now i can easily insert data for authors schema
Authors.js:
router.post('/', (req, res, next) => {
let newAuthor = new Authors({
fullname: req.body.fullname,
address: req.body.address,
phone: req.body.phone,
email: req.body.email
});
newAuthor.save((err, user) => {
if(err) {
res.json({
success: false,
msg: "Failed to add author"
});
} else {
res.json({
success: true,
msg: "Author added successfully"
});
}
});
});
But for posts i am stuck in here
posts.js:
router.post('/', (req, res) => {
var newPost = new Posts({
title: req.body.title,
description: req.body.description,
author:
})
})
main problem is how to get author??
You can set author id in author field.
// you can set authorId in req.body and use that
router.post('/', (req, res) => {
var newPost = new Posts({
title: req.body.title,
description: req.body.description,
author: req.body.authorId
})
});
OR you can set author id in route path and use req.params.authorId
// for that route from ui call should be like
// var userId = 4654654545454
// $http.post('/'+userId)....
router.post('/:authorId', (req, res) => {
var newPost = new Posts({
title: req.body.title,
description: req.body.description,
author: req.params.authorId
})
});
On the page where you allow users to create posts, you need to pass the author's id along with the rest of the post details. Then you can simply refer to the author's id by whatever you chose to send it as (i.e. authorId).
If you are using a serializer that takes all the values from your form and nicely packages them, then insert a hidden input field that stores the author's id, so you can capture that as well. For example:
<input type="hidden" name="authorId" value={user._id} />
Otherwise, if you are manually packaging the form field values, then just add the author's id as another property in the response object. Not sure what you're doing to send the request but say you were using the axios library to send an ajax post to your endpoint you could do this to easily add the author to the response:
const title = document.getElementByNames("title")[0].value
const description = document.getElementByNames("description")[0].value
const author = document.getElementByNames("authorId")[0].value
axios.post("/posts", {title: title, description: description, author: authorId}).then(res => console.log(res))
Related
I know how to query a specific post by id. However I want to use the slug property of the post instead of its id to to query it. How do I do so ?
//Instead of req.params.id, we have req.params.slug instead
//How do get the post in this case if the Post database model has a slug property.
//We have the req.params.slug
//This is what needs to be changed
const post = await Post.findById(req.params.id, (error, post) => {
console.log(error, post)
}).populate('author')
Here is the Post model:
const mongoose = require('mongoose')
const PostSchema = new mongoose.Schema({
title: {
type: String,
required: true
},
subtitle: {
type: String,
required: true,
},
author: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
required: true
},
content: {
type: String,
required: true
},
image: String,
category: String,
subCategory: String,
createdAt: {
type: Date,
default: new Date()
}
})
module.exports = mongoose.model('Post', PostSchema)
you can use find() if you have many documents share the same slug or findOne() if this slug is unique for each document
Post.find({ slug: req.params.slug }, (error, post) => {
console.log(error, post)
});
or
Post.findOne({ slug: req.params.slug }, (error, post) => {
console.log(error, post)
});
Let's say I have an API with a /posts endpoint. Each post in my Mongoose schema has a reference to the user that created it, and each user has an array of references to the posts they created.
When posting as a logged-in user, in order to save that reference I need to send the current logged-in user ID along with the content of the post to the /posts endpoint. I would prefer not to do so through some nested query like /users/:id/posts and then send req.params.id. I would like to post directly to /posts but send the user.id in the request somehow.
User model:
const UserSchema = new Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true,
unique: true
},
password: {
type: String,
required: true
},
posts: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Post'
}]
});
Posts model:
const PostSchema = new Schema({
content: {
type: String,
required: true
},
created: {
type: Date,
default: Date.now
},
user: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
}
});
Create new post (need a way to get the user ID since it won't actually be in req.params)
exports.createPost = async function(req, res, next) {
try {
const { content } = req.body; // ideally would get user ID from here
const post = await db.Post.create({
content,
user: req.params.id
});
const postUser = await db.User.findById(req.params.id);
postUser.posts.push(post.id);
await postUser.save();
const newPost = await db.Post.findById(post.id);
const {id, created} = newPost;
return res.status(201).json({
id,
content,
created
})
}
catch(err) {
return next(err);
}
}
I know I'm probably missing something obvious, but I appreciate any suggestions.
This is my product Schema using mongoose in nodeJs. However I am developing a REST API.
const ImageSchema = new Schema({
path: {
type: String
},
pos: {
type: Number
}
});
const ProductSchema = new Schema({
title: {
type: String,
required: [true, 'Product title is required.']
},
description: {
type: String
},
created_date: {
type: Date ,
required: [true, 'Created Time required.'],
default: Date.now
},
images: [
ImageSchema
]
});
const Product = mongoose.model('product', ProductSchema);
module.exports = Product;
This is how I update a product
router.put('/:id', upload.single('pImg'), function(req, res, next){
var x = req.body;
Product.findByIdAndUpdate({
_id: req.params.id
}, x).then(function(){
Product.findOne({
_id: req.params.id
}).then(function(product){
res.send(product);
});
}).catch(next);
});
My question is how can I push into the images array and also update other fields like title, description at the same time ?
you can use $push and $set in your call.
I'm developing an app using Node.js, Mongoose, MongoDb, express.
I have 2 schemas one for student and one for snippets. I'm using the population model population model. I can create a user, and create a snippet and link it to the user. But I can't link and save the snippets in the user collection.
How to link and save the user so that it can have a reference to his snippets?
user and snippet schema
var userSchema = Schema({
name: { type: String, required: true, unique: true },
password: { type: String, required: true },
snippet: [{ type: Schema.Types.ObjectId, ref: 'Snippet' }]
})
var snippetSchema = Schema({
user: {type: Schema.Types.ObjectId, ref: 'User'},
title: String,
body: String,
createdAt: {
type: Date,
require: true,
default: Date.now
}
})
This is how I save the user which usually when the user register.
var username = request.body.name
var password = request.body.password
var newUser = new User({
name: username,
password: password
})
newUser.save().then(function () {
console.log('success')
response.redirect('/')
})
This is how I save the snippets I add it inside a user .save() function so that it saves the snippet ref but it gives me name.save() is not a function error.
var name = request.session.name.name
name.save().then(function () {
// Using a promise in this case
var newSnippet = new Snippet({
user: name._id,
title: title,
body: snippet
})
newSnippet.save().then(function () {
// Successful
console.log('success')
response.redirect('/')
})
}).catch(function (error) {
console.log(error.message)
response.redirect('/')
})
name.save() is not a function because name is just a string in this case, not a Mongoose object.
One way to do it is to create your user, then retrieve it and add a snippet:
var name = request.session.name.name
User.find({ name: name }).then(function (user) {
// Here you get your user by name
var newSnippet = new Snippet({
user: user._id, // And here you can pass user _id
title: 'your title',
body: 'your snippet'
})
newSnippet.save()
})
I'm trying to create a REST api using express and mongoose. Below is the code for User model (user.server.model.js).
const mongoose = require('mongoose');
var userSchema = new mongoose.Schema({
name: {
first: { type: String, required: true },
last: { type: String, required: true }
},
loginId: { type: String, required: true, unique: true },
password: { type: String, required: true },
location: String,
meta: { age: Number, website: String },
isActive: Boolean,
createdOn: { type: Date, default: Date.now },
updatedOn: Date
});
var User = mongoose.model('User', userSchema);
exports.User = User;
I'm trying to use this User model in express route (routes.js) as below:
const express = require('express'),
User = require('../models/user.server.model'),
router = express.Router();
router.route('/users')
.post((req, res) => {
let user = new User({
name: req.body.name,
loginId: req.body.loginId,
password: req.body.password,
location: req.body.location,
meta: req.body.meta,
createdOn: req.body.createdOn,
updatedOn: req.body.updatedOn
});
user.save((err) => {
if (err) {
res.send(err);
}
else{
res.json({ message: 'User created' });
}
});
});
module.exports = router;
But when I try to test this api using Postman extension in Chrome I'm getting below error
TypeError: User is not a constructor
Node Version: 6.0
Can anyone please advise whats going wrong here.
You're using the require value directly as User, so you should change exports.User to module.exports in user.server.model.js:
module.exports = User;