I am having an issue with node + express routing. I have a routing schema by default provided in the IDE webstorms. I am not sure if I configured everything well, because I am having this error.
I can do a GET /users and POST /users properly with correct results on postman.
routes/users.js
const express = require('express');
const router = express.Router();
const _ = require('lodash');
const {ObjectID} = require('mongodb');
const {mongoose} = require('../db/mongoose')
const {User} = require('../db/models/users')
const {Project} = require('../db/models/projects')
const {Dialog} = require('../db/models/dialogs')
(...)
router.get('/users/:userid', (req, res) => {
var id = req.params.userid.toString();
if (!ObjectID.isValid(id)) {
return res.status(404).send();
}
User.findByID(id).then((user) => {
if (!user) {
return res.status(404).send();
}
res.send({user});
}).catch(() => {
res.status(404).send();
});
});
models/users.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema
// todo refactor userschema with proper validators (view udemy course)
const UserSchema = new Schema({
email: {type: String, required: true},
password: {type: String, required: true},
name: {type: String},
company: {type: String},
phone: {type: String},
projects: [{type: Schema.Types.ObjectId, ref: 'Project'}]
});
const User = mongoose.model('User', UserSchema);
module.exports = {User}
Mikey is right. Mongoose model function is findById() not findByID() - http://mongoosejs.com/docs/api.html#model_Model.findById
Related
I'm not sure how to approach accessing/modifying nested schemas in mongoDB. I have a User schema which has standard info about the user, this also contains a schema for Pages which is a way to organize a user's Bookmarks. I'm developing a backend API that would allow the user to delete a specific bookmark on the page their currently on.
I have a set of mongoose Schema as follows:
user.model.js
const mongoose = require('mongoose');
const Bookmark = new mongoose.Schema({
url: {type: String, required: true, unique: true},
image: {type: String},
title: {type: String},
description: {type: String},
tags: [String],
});
const Page = new mongoose.Schema({
name: {type: String, required: true, unique: true},
image: {type: String},
bookmarks: [Bookmark],
});
const User = new mongoose.Schema({
email: {type: String, required: true, unique: true },
password: {type: String, required: true},
pages: [Page],
},
{collection: 'user-data'}
);
const model = mongoose.model('Userdata', User);
module.exports = model;
I need to build a backend that would remove a specified Bookmark from the current User. Can I simply use findbyIDandRemove()?
index.js
const express = require("express");
const mongoose = require("mongoose");
const jwt = require("jsonwebtoken");
const User = require("./models/user.model");
const app = express();
app.post("/api/remove_bookmark", async (res, req) => {
const token = req.headers["x-access-token"];
try{
const decoded = jwt.verify(token, secret);
const email = decoded.email;
const bookmark = req.body.bookmark;
const user = await User.findOne({email: email});
if(user)
{
await User.findByIdAndRemove(bookmark._id);
}
} catch (err) {
return res.json({status: "error", error: "invalid token"});
}
});
Any help or articles that would pertain to understanding nested schemas would be greatly appreciated.
I write node.js code and try to insert data into a mongodb database by Postman (post) but the data is not saved, only _id and _v are inserted into the documents ,that are entered automatically. I think the problem is in the body-parser, it is deprecated, but I tried a few options and it remained deprecated. (I'm not sure the problem with bodyparser).The data were inserteded via Postman(post). This is the relevant node.js code:
const express = require ('express');
const mongoose = require ('mongoose');
const router = require ('./routes/api');
const bodyParser = require("body-parser");
const dotenv = require('dotenv');
dotenv.config();
const app = express();
.
.
.
app.use(bodyParser.json());//this bodyParser is deprecated
app.use('/',router);
model:
const mongoose = require ('mongoose');
const userSchema = mongoose.Schema({
name:{
type:String,
require
},
password:{
type:String,
minlength:8,
require
}
})
module.exports = mongoose.model('User', userSchema);
controller:
const User = require ('../models/User');
const newUser = async (req,res)=>{
let user1 = new User(
req.body);
console.log(`${user1} added`);
try{
await user1.save();
res.status(200).json({newUser:user1});
}
catch(error){
res.send(`cant save new user: ${error.message}`)
}
}
module.exports = { newUser }
This is what I wrote in Postman:
{
"name":"james",
"password":"12345678"
}
and this is the response:
{
"newUser": {
"_id": "60a68f815019f31cfc098572",
"__v": 0
}
}
I would be very happy to get help !!
Please make the following changes to get the desired result.
// In place of app.use(bodyParser.json()), use
app.use(express.json())
// Controller
const userSchema = require("../models/User");
const newUser = async (req, res) => {
let user1 = new userSchema({
name: req.body.name,
password: req.body.password,
});
console.log(`${user1} added`);
try {
await user1.save().then(() => res.status(201).json({ newUser: user1 }));
} catch (error) {
res.send(`cant save new user: ${error.message}`);
}
};
module.exports = { newUser };
Also, inside the user schema, please change require to required: true.
// Model
const userSchema = new mongoose.Schema({
name:{
type: String,
required: true
},
password:{
type: String,
minLength:8,
required: true
}
})
Modify your model.js file. It will check if anything is missing in req.body
const mongoose = require ('mongoose');
const userSchema = mongoose.Schema({
name:{
type:String,
required: true
},
password:{
type:String,
minlength:8,
required: true
}
})
module.exports = mongoose.model('User', userSchema);
Client.js
const mongoose = require("mongoose");
var Schema = mongoose.Schema;
const clientSchema = new mongoose.Schema(
{
name: { type: String, required: true, default: "" },
}, {
timestamps: true
}
);
module.exports = mongoose.model("Client", clientSchema);
User.js
const mongoose = require("mongoose");
var Schema = mongoose.Schema;
const userSchema = new mongoose.Schema({
name: { type: String, required: true, default: "" },
clients: [{
client: {
type: Schema.Types.ObjectId,
ref: "Client",
default: null
},
user_group: {
type: Number
default: null
}
}]
}, { timestamps: true });
module.exports = mongoose.model("User", userSchema);
auth.js (Where trying to populate Clients)
const express = require("express");
const router = express.Router();
const User = require("../models/User");
const Client = require("../models/Client");
router.post("/users", (req, res) => {
let params = req.body;
let total_client = [];
User.findOne({
email: params.email
})
.populate({
path: "clients.client",
model: Client
})
.exec((err, user) => {
console.log(user);
res.send(user);
});
});
module.exports = router;
Please check the above code. I have given code examples of my two models user.js and client.js. In user schema, I have referenced client inside an array object. While querying user, the client is not population. Please help me to get this thing done. Thanks in advance.
The following expects you to provide a name in the json body of your post request (your example uses email which does not exist in the user model). Also, your model is already defining the ref: Client and so you can simplify your request to just include the path clients.client.
router.post("/users", async (req, res) => {
const { name } = req.body;
const user = await User.findOne({ name: name }).populate('clients.client').exec();
res.send(user);
});
Solved this problem just adding an extra parameter in module export of client.js file
module.exports = mongoose.model("Client", clientSchema, "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'm new to node.js and I am having problem accessing to the when multiple mongoose schema were declare.
//schema.js in model
var mongoose = require('mongoose');
var Schema = mongoose.Schema
, ObjectId = Schema.ObjectId;
//User Schema
var userSchema = new Schema({
id: ObjectId,
firstname: {type: String, require: true},
lastname: {type: String, require: true},
username: {type: String, unique: true, require: true},
password: {type: String, require: true},
role: {type: [String], require: true}
})
var User = mongoose.model('User', userSchema);
module.exports = User;
//Question Schema
var qnSchema = new Schema({
id: ObjectId,
question: {type: String, require: true},
module_id: {type: ObjectId, ref: 'Module'}
})
var Question = mongoose.model('Question', qnSchema);
module.exports = Question;
//Answer Schema
var ansSchema = new Schema({
id: ObjectId,
answer: String,
question: {type: ObjectId, ref: 'Question'}
})
var Answer = mongoose.model('Answer', ansSchema);
module.exports = Answer;
//Module Schema
var modSchema = new Schema({
id: ObjectId,
name: {type: String, require: true}
})
var Module = mongoose.model('Module', modSchema);
module.exports = Module;
//Role Schema
var roleSchema = new Schema({
id: ObjectId,
role: {type: String, require: true}
})
var Role = mongoose.model('Role', roleSchema);
module.exports = Role;
//index.js in controller
var mongoose = require('mongoose');
var User = require('../models/schema');
var db = mongoose.connect('mongodb://localhost/damai');
module.exports = function(app) {
app.get('/', function(req, res) {
if (typeof req.session.userid == 'undefined') {
res.render('login', { title: app.get('title') });
} else {
res.render('index', { title: app.get('title') });
}
});
app.post('/login', function(req, res) {
passwordVerification(req, res);
});
}
function passwordVerification(req, res)
{
var userid = req.param('userid');
var password = req.param('password');
User.findOne({'username': userid},{'password': 1}, function(err, cb)
{
console.log(cb);
if(cb!= null)
{
if (password == cb.password) {
req.session.userid = userid;
res.render('index', { title: app.get('title'), 'userid': userid });
} else {
res.render('login', { title: app.get('title'), error: 'Invalid login'});
}
}
else
{
res.render('login', { title: app.get('title'), error: 'Invalid login'});
}
});
}
When I only have the "User Schema" in my schema.js, the database call from method "passwordVerification()" from index.js will return me the relevant password that was retrieve from the database. However, when I start adding in other schema such as "Question Schema" in schema.js, the method "passwordVerification()" will always return null.
When exporting multiple models from a single file like you are in schema.js, you need to give each exported model its own exports field name.
For example, replace the multiple module.exports = ... lines in schema.js with this code at the end of the file that exports all models:
module.exports = {
User: User,
Question: Question,
Answer: Answer,
Module: Module,
Role: Role
};
And then in index.js you can access the models like so:
var models = require('./schema');
...
models.User.findOne(...