I'm quite new to mongoose. I have found similar questions on here that do answer them, but they are not quite like my problem / I can't find out how it's similar.
I'm trying to push a subdocument into an array on my parent document. Currently I do that like this:
Upload-soundboard
const multer = require('multer')
const FILE_PATH = 'uploads'
const passport = require('passport')
const strategy = require('../strategies/strategy')
const upload = multer({
dest: `${FILE_PATH}/`
})
const { Soundboard } = require('../models/soundboard')
const express = require('express')
const router = express.Router()
passport.use(strategy.jwtStrategy)
router.post('/', passport.authenticate('jwt', { session: false }), async (req, res) => {
try {
//console.log(req.body.name)
req.user.soundboards.push({
name: req.body.name,
})
//console.log(req.user.soundboards)
await req.user.save()
res.send('Success!')
} catch (err) {
res.status(500).send(err)
}
})
module.exports = router
This does in fact push a subdocument to the array, but it only adds the Object.ID, and not the name I requested. The schema's look like this:
USER
const User = mongoose.model('User', new mongoose.Schema({
name: {
type: String,
required: true,
minlength: 5,
maxlength: 50
},
email: {
type: String,
required: true,
minlength: 5,
maxlength: 255,
unique: true
},
password: {
type: String,
required: true,
minlength: 5,
maxlength: 1024
},
soundboards: [SoundboardSchema]
}))
SOUNDBOARD
const Soundboard = new Schema({
name: {
type: String,
required: true,
minlength: 5,
maxlength: 50
},
sounds: {
type: [SoundSchema],
required: false
}
})
SOUND
const Sound = new Schema({
name: {
type: String,
required: true,
minlength: 5,
maxlength: 50
},
path: {
type: String,
required: true
}
})
Does anyone see the answer? Thanks in advance!
This is how you should use it instead:
router.post('/', passport.authenticate('jwt', { session: false }), async (req, res) => {
try {
let newSoundboards = {
name: req.body.name,
}
//I don't see you loading your model somewhere with the connection
//So I used yourDB as an example.
await new yourDB(newSoundboards).save()
res.send('Success!')
} catch (err) {
res.status(500).send(err)
}
})
Related
I'm learning the MERN stack and trying to create an authentication, but now I have a problem, whenever I'm trying to register, I have an error 'TypeError: User.create is not a function'.
I think that I have a problem with user model or export. Please help
INDEX.JS
const express = require("express");
const mongoose = require("mongoose");
const cors = require("cors");
const dotenv = require("dotenv");
const app = express();
const User = require("./models/User");
dotenv.config({ path: "./.env" });
app.use(express.json());
app.use(cors());
mongoose.connect(process.env.MBD_CONNECT, { useNewUrlParser: true }, (err) => {
if (err) return console.error(err);
console.log("Connected to MongoDB");
});
app.post("/api/registr", async (req, res) => {
console.log(req.body);
try {
const user = await User.create({
firstName: req.body.firstName,
lastName: req.body.lastName,
email: req.body.email,
password: req.body.password,
});
res.json({ status: "ok" });
} catch (err) {
console.log(err);
res.json({ status: "error", error: "Duplicate email" });
}
});
app.post("/api/login", async (req, res) => {
const user = await User.findOne({
email: req.body.email,
password: req.body.password,
});
if (user) {
return res.json({ status: "ok", user: true });
} else {
return res.json({ status: "error", user: false });
}
});
app.listen(3001, () => {
console.log("SERVER RUNS PERFECTLY!");
});
USER.JS (MODEL)
const mongoose = require("mongoose");
const User = new mongoose.Schema({
firstName: { type: String, required: true },
lastName: { type: String, required: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
});
const model = mongoose.model("UserData", User);
module.exports = User;
You're exporting the schema, not the model. create is a method of mongoose Model class, see document here.
const model = mongoose.model("UserData", User);
module.exports = User; // <------ problem here
It should be:
const model = mongoose.model("UserData", User);
module.exports = model;
Your model file please update with the following code snip
const mongoose = require("mongoose");
const User = new mongoose.Schema({
firstName: { type: String, required: true },
lastName: { type: String, required: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
}, { collection : 'UserData'});
const model = mongoose.model("UserData", User);
module.exports = User;
i am try to inser user data into my database but data is not inserting and it is showing like User already exist with this email
How can solve this one ?
My code is below
i had tried with different email even though it is User already exist with this email and it is not inserting in the database.
server.js
require("dotenv").config();
const express = require("express");
const app = express();
const mongoose = require("mongoose");
const port = process.env.PORT || 3500;
app.use(express.json());
//DB connection
mongoose
.connect(process.env.MONGO_URL)
.then(() => console.log("DB Connection Successful"))
.catch((err) => console.log(err));
//Routes
app.use("/api/auth/", require("./routes/auth"));
app.listen(port, () => {
console.log("Server is running on Port " + port);
});
user.js
const mongoose = require("mongoose");
const bcrypt = require("bcrypt");
const userSchema = new mongoose.Schema(
{
firstName: { type: String, required: true, trim: true, min: 3, max: 30 },
lastName: { type: String, required: true, trim: true, min: 3, max: 30 },
userName: {
type: String,
required: true,
trim: true,
min: 3,
max: 30,
unique: true,
index: true,
lowercase: true,
},
email: {
type: String,
required: true,
trim: true,
unique: true,
lowercase: true,
},
userPassword: { type: String, required: true },
role: { type: String, enum: ["user", "admin"], default: "admin" },
contactNumber: { type: String },
profilePicture: { type: String },
},
{ timestamps: true }
);
userSchema.virtual("password").set(function (password) {
this.userPassword = bcrypt.hashSync(password, 10);
});
userSchema.methods = {
authenticate: function (password) {
return bcrypt.compareSync(password, this.userPassword);
},
};
module.exports = mongoose.model("User", userSchema);
auth.js
const router = require("express").Router();
const User = require("../models/user");
router.post("/signin", (req, res) => {});
router.post("/register", async (req, res) => {
const user = User.findOne({ email: req.body.email });
if (!user) {
const newUser = new User(req.body);
await newUser.save();
res.status(201).json({
user: newUser,
});
} else {
res.status(400).json({
message: "User already exist with this email",
});
}
});
module.exports = router;
please find the attached images
Querying the database is an asynchronous function call.
Here at the auth.js, You're checking asynchronous if the user exits. const user = User.findOne({ email: req.body.email });
You should add await like that: const user = await User.findOne({ email: req.body.email });
Since, its asyncourouns Javascript doesn't wait for the answer and assings undefined to the user variable.
Therefore you end up at your else statement.
I am working on a blog app. Here one user has a one-to-many relationship with posts.After creating the basic CRUD I wanted to make a profile page featuring all the posts of a single User. I am following all the steps but still when I fetch all users I get empty array of Post.
And also I am trying to get user name in each post instead of only ID. I am using Populate but still getting only user id back.
router.get('/', auth, async (req, res) => {
try {
const Posts = await Post.find()
.sort({
date: -1
})
.populate('users');
res.json(Posts);
} catch (err) {
console.error(err.message);
res.status(500).send('Server Error');
}
});
Here's my user schema
const mongoose = require('mongoose');
const UserSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
posts: [
{
type: mongoose.Schema.Types.ObjectId,
ref: 'Post'
}
],
email: {
type: String,
required: true,
unique: true
},
password: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
}
});
const User = mongoose.model('user', UserSchema);
module.exports = User;
Here's Post Schema
const mongoose = require('mongoose');
const PostSchema = new mongoose.Schema({
user: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
},
title: {
type: String,
required: true
},
content: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
}
});
const Post = mongoose.model('post', PostSchema);
module.exports = Post;
I am following all the steps but still when I fetch all users I get empty array of Post
When you add a new post you must also update the posts field of the userSchema:
const newPost = await Post.insert(/* post */);
await User.findOneAndUpdate({ _id: newPost.user }, { $push: { posts: newPost._id }, { new: true });
And also I am trying to get user name in each post instead of only ID. I am using Populate but still getting only user id back
Try .populate('user'); without s
I'm practicing creating models and routes and am using postman to send a POST request to test it out. However, I keep getting the user is not a constructor error.
index.js (route)
const express = require('express')
require('./db/mongoose')
const User = ('./models/user')
const app = express()
const port = process.env.PORT || 3000
app.use(express.json())
app.post('/users', (req, res) => {
const user = new User(req.body)
user.save().then(() => {
res.send(user)
}).catch(() => {
})
})
app.listen(port, () => {
console.log(port + ' is aliiiiiiiive!')
})
User (schema)
const mongoose = require('mongoose')
const validator = require('validator')
const User = mongoose.model('User', {
name: {
type: String,
required: true,
trim: true
},
email: {
type: String,
require: true,
trim: true,
lowercase: true,
validate(value) {
if(!validator.isEmail(value)) {
throw new Error('Email is invalid')
}
}
},
age: {
type: Number,
default: 0,
validate(value) {
if(value < 0) {
throw new Error('Age must be a positive number.')
}
}
},
password: {
type: String,
trim: true,
lowercase: true,
required: true,
minlength: 7,
validate(value) {
if( value.toLowerCase().includes("password")) {
throw new Error("Password can't be 'password'.")
}
}
}
})
module.exports = User
mongoose.js
const mongoose = require('mongoose')
mongoose.connect('mongodb://127.0.0.1:27017/task-manager-api', {
useNewUrlParser: true,
useCreateIndex: true
})
I expect it to send back an object with the following information I'm sending on Postman:
{
"name": "Michael",
"email": "email#eail.com",
"password": "ThisIsAPassword"
}
You have to define a userSchema before compiling the model, like this:
const mongoose = require('mongoose')
const validator = require('validator')
const userSchema = new mongoose.Schema({
name: {
type: String,
required: true,
trim: true
},
email: {
type: String,
require: true,
trim: true,
lowercase: true,
validate(value) {
if(!validator.isEmail(value)) {
throw new Error('Email is invalid')
}
}
},
age: {
type: Number,
default: 0,
validate(value) {
if(value < 0) {
throw new Error('Age must be a positive number.')
}
}
},
password: {
type: String,
trim: true,
lowercase: true,
required: true,
minlength: 7,
validate(value) {
if( value.toLowerCase().includes("password")) {
throw new Error("Password can't be 'password'.")
}
}
}
})
const User = mongoose.model('User', userSchema);
exports.User = User
Now it is a constructor, because we are saying each instance of User is a new instance of userSchema.
I figured it out. On the third in my index.js file, I left out require.
Instead of this:
const User = ('./models/user')
It should have been this:
const User = require('./models/user')
Thanks for all your help, everyone!
Hi friends i have this schema in my db
const impresionSchema = mongoose.Schema({
id:{type:Number, required: true},
ap:{type:String, required: true},
mac_address:{type:String, required: true},
campaniaId:{type:String, required: true}
}, {versionKey: false});
and this is my query to db
router.get("/:start/:end", (req, res, next) => {
const start = parseInt(req.params.start);
const end = parseInt(req.params.end);
const unique = req.query.unique !== undefined;
Impresion.find({id:{$gte:start, $lte:end}}).then(impresiones => {
res.status(200).json({
message: "Impresiones fetched successfully!",
impresiones: impresiones
});
});
});
Mongo does not return any data, but there are multiple documents according to the query
**sorry for my english
Use it like this:
Impressions.find({id:{$gte:start, $lte:end}}).toArray().then(arr => {}).catch()
I think you missed exporting the schema so export schema like: -
var mongoose = require('mongoose');
var db = mongoose.createConnection(your hostname, you database name');
const impresionSchema = mongoose.Schema({
id:{type:Number, required: true},
ap:{type:String, required: true},
mac_address:{type:String, required: true},
campaniaId:{type:String, required: true}
}, {versionKey: false});
var Impresion = db.model('Impresion', impresionSchema);
module.exports = Impresion; // this is what you want