I use mongoose to populate "Post Schema" with information about users whic create the post.
postModule.js
const mongoose = require('mongoose');
const postSchema = mongoose.Schema({
title:String,
description:String,
datePost:Date,
images:[String],
like:[String],
dislike:[String],
author:{
type: mongoose.Schema.Types.ObjectId,
ref:'User'
},
});
postSchema.pre(/^find/,function(next){
this.populate({
path:'author',
select:'photo firstName lastName'
});
next();
});
const Post = mongoose.model('Post',postSchema);
module.exports = Post;
This is the controller build in postController.js
//Get All User Post
exports.getUsersPost = catchAsync(async(req,res,nex)=>{
const userPost = await Post.find({author:req.params.userId});
res.status(200).json({
status:"success",
length:userPost.length,
data:{
post:userPost
}
});
});
postRouter.js
router.route('/get-user-posts/:userId').get(authController.protect,postController.getUsersPost)
I don't know what is wrong, I recive in postman this error Cannot GET /api/v1/get-user-posts/5f719092ba22b8373c72196
There is any option to resolve this problem and the result of request it must to by all the posts created by the user.
If your app.js looks like below, then you endpoint should be:
/api/v1/post/get-user-posts/5f719092ba22b8373c72196.
It takes the whole string in the use() function. So /api/v1/user/**Routes you've defined in your Routes files**
const sessionRoutes = require('./routes/sessionsRoutes');
const userRoutes = require('./routes/userRoutes');
const viewRoutes = require('./routes/viewRoutes');
const postRoutes = require('./routes/postRoutes');
app.use('/api/v1/session',sessionRoutes);
app.use('/api/v1/user',userRoutes);
app.use('/api/v1/post',postRoutes);
app.use('/',viewRoutes);
module.exports = app;
Also add and extra slash just to be sure app.use('/api/v1/user/', userRoutes)
Related
Making a MongoDB call from a react component on Form Submit with Mongoose throws an error - TypeError: Group is not a constructor at below line
let group1 = new Group
I have a server file inside which I initialize the connection.
server.js
const mongoose = require('mongoose');
mongoose.connect('dbName',{ useNewUrlParser: true });
mongoose.connection.once('open',() =>{
console.log('connected to the database');
});
Then there is a model file called group.js
const mongoose = require('mongoose');
var groupSchema = new mongoose.Schema({
groupName: String
});
module.exports = mongoose.model('Group',groupSchema);
Component CreateNew
const Group = require('../models/group');
class CreateNew extends Component {
// code here
render()
// code here
<Form onSubmit = {e => {
let group1 = new Group({
groupName: 'My Group'
});
group1.save(function(err,group1){
if (err) return console.log(err);
console.log('mongo success');
});
}}>
When I put all the code in one place like this inside the server.js file then the code works and I can see the data in Mongo.
If I just shift the code from inside Form's onSubmit to before the 'class CreateNew extends Component' line just for testing then it throws following error
Cannot overwrite Group model once compiled.
at this line
module.exports = mongoose.model('Group',groupSchema);
I'll show you a short overview of the project, which includes frontend and backend.
BACKEND
1.1 server.js
const express = require('express');
const app = express();
const port = process.env.PORT || 80;
const http = require('http').Server(app);
const mongoose = require('mongoose');
const routes = require(path_to_api.js)(router);
app.use('/myApi', routes)
//***Here you should implement more details about your project such as routes, body parsers and other middlewares*****//
mongoose.connect('mongodb://localhost:27017/your-app-name', err => err?console.log(err):console.log('Successfully connected to MongoDB'));
http.listen(port, ()=> console.log(`Server running on ${port}`))
1.2 Model, group.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
let groupSchema = new Schema({
groupName: {
type: String
}
});
module.exports = mongoose.model('Group',groupSchema);
1.3 api.js (Still backend!!!)
const Group = require(path_to_group.js);
module.exports = router => {
router.post('/group', (req, res)=> {
let group = new Group();
group.groupName = req.body.groupName;
//Save in database
group.save(function(err){
...
})
}
return router
}
FRONTEND
2.1 Ajax calls (service.js)
function group(data){
return fetch('/api/authenticate',{
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-type': 'application/json'
},
body: JSON.stringify(data)
}).then(response => response.json()).then(data => {
return data //Server response
})
}
export {group}
2.2 React Component
import {group} from //service.js path
class CreateNew extends Component {
constructor(props, context){
this.sendGroupName = this.sendGroupName.bind(this);
}
this.sendGroupName(){
let data = //data received from form after submit
//It is the most important part from the frontend - sending data to the server
group(data).then(res => {
//do somenthing with servers response
}
}
render(){
<Form onSubmit={this.sendGroupName}>
//Form content such as inputs, labels...
<Form/>
}
That is my quickly explanation concerning MEAN projects. I hpe it will be useful for you.
I have this schema in mongoose.
I want to delete a author that will deletes all author's stories.
is best way to do that in middleware express or middleware mongoose?
thanks
const authorSchema = new Schema ({
name : String,
stories : [{ type : ObjectId, ref:'Story'}]
})
const storySchema = new Schema({
title : String
})
Since it involves directly interacting with Mongoose and MongoDB, I'd suggest doing it in Mongoose middleware. Here's how you'd remove all the stories from a certain Author object:
let myAuthor = new Author(/* all the props */);
myAuthor.stories = [];
You can use Mongoose 'remove' middleware.
For example:
authorSchema.pre('remove', (next) => {
storySchema.remove({authorSchema_id: this._id}).exec();
next();
});
And documentation.
I am writing a node/express rest api.
Hitting,
http://localhost:5000/api/news
and
http://localhost:5000/api/news/?id=c5f69d56be40e3b56e55d80
both give me all the news objects because it enters the same .getNews function on for both the urls.
My controller:
const NewsController = {};
const News = require('../models/news.model');
// This implementation of getNews is using Promises
NewsController.getNews = function(req, res) {
console.log('Inside getNews');
sendResponse = function(arg) {
res.json(arg);
}
const allnews = News.find({}, function(err, ns) {
sendResponse(ns);
});
};
// ES6 style
NewsController.getSingleNews = async (req, res) => {
console.log("Inside getSingleNews");
const news = await News.findById(req.params.id);
res.json[news];
};
NewsController.createNews = async (req, res) => {
const news = new News(req.body);
await news.save();
res.json[{
'status': 'item saved successfully'
}];
};
NewsController.deleteNews = async (req, res) => {
await News.findByIdAndRemove(req.params.id);
res.json[{
'status': 'item deleted successfully'
}]
};
module.exports = NewsController;
My routes.js (I am using the router at /api. So app.js has // use Router
app.use('/api', newsRoutes);
)
const express = require('express');
const router = express.Router();
var newsController = require('../controllers/NewsController')
router.get('/news', newsController.getNews);
router.get('/news/:id', newsController.getSingleNews);
router.post('/news', newsController.createNews);
router.delete('news/:id', newsController.deleteNews);
module.exports = router;
My Model
const mongoose = require('mongoose');
const { Schema } = mongoose;
const newsSchema = new Schema({
title: { type: String, required: true },
content: { type: String, required: true },
author: { type: String },
image: { type: String },
source: { type: String }
});
module.exports = mongoose.model('news', newsSchema);
The issue with your code is the way you are trying to call your endpoint. Express routes don't match query string parameters.
Having said that, your call to the news endpoint that looks like this:
http://localhost:5000/api/news/?id=c5f69d56be40e3b56e55d80
Should look like this instead:
http://localhost:5000/api/news/c5f69d56be40e3b56e55d80
That way the id parameter will get mapped to the req.params.id property inside your getSingleNews controller.
Being that the expected behavior for the way you declared your route:
router.get('/news/:id', newsController.getSingleNews);
For more information on how express routes work, check the documentation here: https://expressjs.com/en/guide/routing.html
Use /news/:id first. Your request will be redirected to the first matched url following the declaration order.
So /api/news satisfies app.get(/news)? Yep, gets redirected to that controller.
/api/news/?id=c5f69d56be40e3b56e55d80 satisfies app.get(/news)? Yep, also gets redirected to /news controller.
By the way, as your getting the id from req.params you should use /news/c5f69d56be40e3b56e55d80. If you were to get it from req.query you wouldn't need another route. /news?id=c5f69d56be40e3b56e55d80 would be perfect, you'd just need to check the existence of req.query.
I'm trying to build a simple blog with a MEAN stack and I'm currently setting up the back end. I'm testing my routes with Postman and for some reason, I can't save the title and body of a post in the DB.
My model:
models/posts/db.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var PostSchema = new Schema ({
title: { type: String },
body: { type: String },
date: { type: Date, default: Date.now }
});
module.exports = mongoose.model('Post', PostSchema);
My controller: controllers/posts.index.js
var base = process.env.PWD;
var Post = require(base + '/models/posts/db.js')
var createPost = function(req, res) {
var post = new Post(req.body)
post.save(function(err, post) {
if(err) { res.sendStatus(500, err); }
res.json(post);
})
}
var getPosts = function(req, res) {
Post.find(function(err, posts) {
if (err) { res.sendStatus(500, err); }
res.json(posts);
})
};
module.exports = {
createPost,
getPosts
}
And here are my main routes in routes/index.js
router.get('/posts', posts.getPosts);
router.post('/posts/create', posts.createPost);
module.exports = router;
And my main server is using a /api endpoint:
`app.use('/api', routes);`
So in Postman, when I send a POST request to /api/posts/create with a post containing a title and a body, an empty post is stored. I get something like this inserted:
{
"__v": 0,
"_id": "5a29de91521f168eb9e1bcf2",
"date": "2017-12-08T00:36:33.280Z"
}
Any help would be appreciated.
It looks like the Post may not be getting the body of your actual post. You can fill the body property on your request with the body-parser module. Do an npm install body-parser and add this to your code:
const bodyParser = require('body-parser')
app.use(bodyParser.json())
I figured it out, 2 problems:
The order of where you place body-parser is important, I wrote the line after setting my routes so it wasn't parsing anything.
I hadn't set up my Postman correctly, it was sending regular text instead of a JSON object. facepalm
I'm building an app using node-webkit, based on expressjs and mongoose. I'm new to basically all of this.
I've got a mongoDb hosted online and i'm try to use it in my app, but i'm missing something
I created in model folder db.js, where i connect with the db
var mongoose = require('mongoose');
mongoose.connect('mongodb://user:password#ds012345.mlab.com:port/mydb') //this isn't the real link
then my model, clients.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var clientSchema = new Schema ({
name: String,
//other fields
});
var client = mongoose.model('client', clientSchema);
module.exports = client;
Then, in my app.js
var db = require('./model/db')
I'm also using routes, so in my index.js i got
var client = require('../model/clients')
But i cannot use any function (save, find, ecc.), i can just create models.
I think I'm not connecting in the right way all the modules, i was previously using diskdb and i connected to it in my index.js, but i tried in the same way and it doesn't work anyway.
Also, when i build the app, my mongoose connection status is 2.
Here are a few things:
what is ecc? you should connect to something like this: mongoose.connect('mongodb://localhost:27017/test');
27017 is the default port for MongoDB and test is the name of your database. Also make sure you start mongo server with mongod then run mongo console mongo.
Your field should specify type of the data:
var clientSchema = new Schema ({
name: String,
age: Number
});
So you want to save the document into database:
var client = mongoose.model('client', clientSchema);
var data = {
nome: 'something'
};
var user = new client(data);
user.save(function(err) {
if(err) console.log(err);
});
In your route, you can do something like this to query back and send data back to the req:
var express = require('express');
var router = express.Router();
var clientSchema = require('../models/clientSchema');
router.get('/', function(req, res, next) {
UserSchema.find({} , function(err, data) {
if (err) console.log(err);
res.render('index', {
data: data
});
});
});
module.exports = router;
Hope this help!