post image to mongodb using express nodejs - node.js

I'm trying to post to mongodb using express nodejs and this is the code of add route:
router.post('/add', (req, res) => {
const validating = userValidating(req.body);
if (validating.error) {
res.status(400).send(validating.error.details);
} else {
var path = "images/"+req.file.image;
res.send(path);
var image = req.files.image;
fileName = uuidv1();
const user = new User({
_id: new mongoose.Types.ObjectId(),
image: req.file.image,
title: req.body.title
});
const v = user.validateSync();
if (v)
res.status(400).send('somthing wrong');
user.save()
.then(result => {
res.send('You have added a new user');
image.mv(`./public/images/${fileName}.png`, function(err) {
if (err)
return res.status(500).send(err);
res.send('File uploaded!');
});
console.log(result);
})
.catch(err => {
res.status(401).send(err);
console.log(err);
});
}
});
and this is the function of validation that I used above:
function userValidating(user) {
const userSchema = {
'image': Joi.string().required(),
'title': Joi.string().required()
}
return Joi.validate(user, userSchema);
}
when I tried in postman using form-data like this:
you can see that I get this error of image is required even if I change the image to req.body.image instead of req.file.image
also I tried to use Body raw in postman instead of form-data and write json like this:
{
"image": "uuu",
"title": "uuuu"
}
and it works fine
what's the problem with code?

Related

Mongoose .save() not working inside Node/Express backend API

PostsRouter.post("/ALL", (req, res) => {
const { subreddit, title, user, body } = req.body;
const post = new PostMessage({
postID: uuidv4(),
subreddit: subreddit,
title: title,
user: user,
body: body,
});
console.log(post);
async function _internal() {
try {
const newPost = await post.save();
res.status(201).json(newPost);
} catch (error) {
res.status(400);
}
}
_internal();
});
This function exactly as it is was working earlier but now this method and another PATCH method I defined elsewhere are failing because the promise is never fulfilled on the first line of the try block that saves the new data to the database "const newPost = await post.save()". Would anyone know what could be causing an issue like this? When I make a call to this API there are no error messages from the backend. I also included an image showing how I am making the POST request and the error I am getting.
If you want to create a document in the database and use that document for any further operations then you can use the below code for that purpose.
PostsRouter.post("/ALL", async(req, res) => {
const { subreddit, title, user, body } = req.body;
try {
// PostMessage is the Model
const newPost = await PostMessage.create({
postID: uuidv4(),
subreddit: subreddit,
title: title,
user: user,
body: body,
});
console.log(newPost);
res.status(201).json(newPost);
}catch (error) {
res.status(400);
}
}
});
Hope this helps.

TypeError: newUser.find is not a function

I am very new to the MERN stack and I would like some help figuring out this error. I'm trying to check if an email is already in the database upon creating a new user. Can anyone tell me why I am getting this error?
The model and scheme
//schema
const Schema = mongoose.Schema;
const VerificationSchema = new Schema({
FullName: String,
email: String,
password: String,
date: Date,
isVerified: Boolean,
});
// Model
const User = mongoose.model("Users", VerificationSchema);
module.exports = User;
The Api
const express = require("express");
const router = express.Router();
const User = require("../Models/User");
router.get("/VerifyEmail", (req, res) => {
console.log("Body:", req.body);
const data = req.body;
const newUser = new User();
newUser.find({ email: data.email }, function (err, newUser) {
if (err) console.log(err);
if (newUser) {
console.log("ErrorMessage: This email already exists");
} else {
console.log("This email is valid");
}
});
res.json({
msg: "We received your data!!!",
});
});
module.exports = router;
The api caller using axios
const isEmailValid = (value) => {
const info = {
email: value,
};
axios({
url: "http://localhost:3001/api/VerifyEmail",
method: "get",
data: info,
})
.then(() => {
console.log("Data has been sent");
console.log(info);
})
.catch(() => {
console.log("Internal server error");
});
};
if you have body in your request, change the type of request to POST...
after that for use find don't need to create a instance of model, use find with Model
router.get("/VerifyEmail", (req, res) => {
console.log("Body:", req.body);
const data = req.body;
User.find({ email: data.email }, function (err, newUser) {
if (err) console.log(err);
if (newUser) {
console.log("ErrorMessage: This email already exists");
} else {
console.log("This email is valid");
}
});
res.json({
msg: "We received your data!!!",
});
});
I prefer to use async/await and don't use Uppercase world for routing check the article: like this
router.post("/verify-email", async (req, res) => {
try {
let { email } = req.body;
let newUser = await User.findOne({ email });
if (newUser) {
console.log("ErrorMessage: This email already exists");
} else {
console.log("This email is valid");
}
} catch (error) {
res.json({
msg: "somthing went wrong",
});
}
res.json({
msg: "We received your data!!!",
});
});
The proper way to query a Model is like so:
const User = mongoose.model('Users');
User.find({<query>}, function (err, newUser) {...
So you need to get the model into a variable (in this case User) and then run the find function directly against it, as opposed to running it against an object you instantiate from it. So this is incorrect:
const newUser = new User();
newUser.find(...
So assuming all your files and modules are linked up correctly, this should work:
const User = require("../Models/User");
User.find({<query>}, function (err, newUser) {...
The problem wasn't actually the mongoose function but I needed to parse the object being sent.
let { email } = JSON.parse(req.body);
Before parsing the object looked like {"email" : "something#gmail.com"}
and after parsing the object looked like {email: 'something#gmail.com'}
I also changed the request from 'get' to 'post' and instead of creating a new instance of the model I simply used User.find() instead of newUser.find()

How to delete a doc with id with mongoose?

I want to delete a doc with id in mongoose. It executes the method but doesn't delete that doc in MongoDB Altas.
Note:Everthing is correct and also Passing id correctly in PostMan.
here is my controller :
const Post = require("../models/Post");
const mongoose = require("mongoose");
exports.postPost = async (req, res) => {
try {
const post = await new Post({
_id: new mongoose.Types.ObjectId(),
title: req.body.title,
desc: req.body.desc,
}).save();
console.log("Saved in db!");
return res.status(201).json({
success: true,
data: post,
});
} catch (error) {
return res.status(500).json({
success: false,
message: "Server Error",
});
}
};
exports.deletePost = async (req, res) => {
let postID = req.params.id;
await Post.deleteOne({ _id: postID }, (err, data) => {
if (err) {
res.status(500).json({
message: "Something went wrong, please try again later.",
});
} else {
res.status(200).json({
message: "Post Deleted",
data: data,
});
}
});
};
here is my posts route:
const express = require("express");
const router = express.Router();
const {
postPost,
deletePost,
} = require("../controllers/posts_controller");
router.route("/:id").delete(deletePost);
router.route("/").post(postPost);
module.exports = router;
here is my postman :
here is my mongodb altas:
use the findOneAndDelete({_id:postId}) instead of deleteOne in posts controller
Or
use findByIdAndDelete(postId) instead of deleteOne in posts controller
exports.deletePost = async (req, res) => {
let postID = req.params.id;
await Post.findByIdAndDelete(postID, (err, data) => {
if (err) {
res.status(500).json({
message: "Something went wrong, please try again later.",
});
} else {
res.status(200).json({
message: "Post Deleted",
data: data,
});
}
});
};

array of objects won't POST into mongodb

I have an array of objects that is defined in mongoose schema as
blacklistGroup: {
userId: { type: String },
username: { type: String }
}
I can't figure out why it won't POST into mongodb.
I have a console.log that shows that it represents it's schema, but it never appears in mongodb? What am I doing wrong?
console.output
req.body.blacklistGroup
[ { userId: '5e2350c7f88cfb331c4f67de', username: 'artist1' },
{ userId: '5e20c5a139a92512cc7df63c', username: 'artist' } ]
[object Object]
app.js
app.post("/api/listings", checkAuth, (req, res, next) => {
console.log("req.body.blacklistGroup");
console.log(req.body.blacklistGroup);
let blacklistGroup = req.body.blacklistGroup;
console.log("req.body.blacklistGroup");
const post = new Post({
blacklistGroup: req.body.blacklistGroup,
});
//saves to database with mongoose
post.save().then(result => {
console.log(result);
res.status(201).json({
message: "Auction listing created successfully!",
postId: result._id
});
});
});
You can store all user at once. use mongoose insertMany
const Post = require('post'); //mongoose schema
app.post("/api/listings", checkAuth,(req, res, next) => {
console.log("req.body.blacklistGroup");
console.log(req.body.blacklistGroup);
let blacklistGroup = req.body.blacklistGroup;
console.log("req.body.blacklistGroup");
const blacklistGroup = req.body.blacklistGroup;
(async function(){
await Post.insertMany(blacklistGroup);
res.status(200).send('Ok');
})();
});
Or you can use
const Post = require('post'); //mongoose schema
app.post("/api/listings", checkAuth,async (req, res, next) => {
console.log("req.body.blacklistGroup");
console.log(req.body.blacklistGroup);
let blacklistGroup = req.body.blacklistGroup;
console.log("req.body.blacklistGroup");
const blacklistGroup = req.body.blacklistGroup;
await Post.insertMany(blacklistGroup);
res.status(200).send('Ok');
});
For More Here
You don't have an array of objects (or at least you don't want one), you have an object with two properties; userId and username. MongoDB is expecting JSON and it looks like you're trying to send it an array containing that object.
Try this:
let blacklistGroup = req.body.blacklistGroup[0];
To process an array of objects passed as req.body.blacklistGroup, you will have to iterate over it, define a new Post for each object and then send it. I think part of the confusion here is that your Schema is called blacklistGroup but it doesn't refer to a group, it refers to one entry.
const dbCalls = blacklistGroup.map(userObject => {
const post = new Post({
blacklistGroup: {
userId: userObject.userId,
username: userObject.username
});
return new Promise((resolve, reject) => {
post.save.then(() => {
resolve();
})
.catch(err => {
reject(err);
})
})
});
Promise.all(dbCalls).then(() => {
res.status(201).json({message: "Auction listings created successfully!"})
})
.catch(err => {
res.status(500).json({error: err})
});

404 Not found when upload files nodejs

I am using multer package
I have two ways of uploading images to my server one is with Array and the other is using fields.
The only thing that works is the uploadArray for the /status route.. when i'm uploading to /update it gives me this error SyntaxError: Unexpected token < in JSON at position 0.. The controller for the /update is just the same as the postController.js the only difference it that i update fields instead of save new one.
/utils/lib/account.js
const storage = multer.memoryStorage();
// These two image might be available in the req.files depending on what was sent
const upload = multer({storage}).fields([{ name: 'photo', maxCount: 1 }, { name: 'cover', maxCount: 1 }]);
const uploadArray = multer({storage}).array('image', 12);
exports.upload = (req, res, next) => {
upload(req, res, function (err) {
if (err) {
console.log(err);
}
next();
});
};
exports.uploadArray = (req, res, next) => {
uploadArray(req, res, function (err) {
if(err){
console.log(err);
}
next();
});
};
/routes.js
router.route('/status')
.all(helper.verifyToken)
.all(helper.uploadArray)
.get(status.get)
.post(status.new) // file uploads
.delete(status.delete);
router.route('/update')
.all(helper.verifyToken)
.all(helper.upload)
.post(account.update_profile) // file uploads
The only thing that works here is the uploadArray
/postController.js
new:
(req, res) => {
const uri = new DataUri();
const promises = [];
const images = [];
//Get buffer from files
for(let key in req.files){
const obj = req.files[key];
uri.format('.png', obj.buffer);
let uriContent = uri.content;
promises.push(uploadAsync(uriContent)); //upload each image
}
//Init upload
function uploadAsync(buffer){
return new Promise((resolve, reject) => {
cloudinary.v2.uploader.upload(buffer, function(error, result) {
if(error){
reject(error);
}
if(result.url){
images.push(result.url);
resolve(images);
}
});
});
}
Promise.all(promises)
.then(results => {
// Init post model
console.log('test1')
const post = new Post({
post_img: images,
post_description: req.body.description,
post_by: req.body.id,
photoURL: req.body.id,
post_comments: []
});
// Save data
post.save(function(err) {
if(err) {
res.send(err);
}
var leanObject = post.toObject(); // Transform instance to plain JS Object for modification
// Modifications
leanObject['post_by'] = {
_id: leanObject['post_by'],
display_name: req.body.user, // Add current user display name
photo_url: req.body.user_photo
};
res.json({message: 'Success', type: 'success', code: 200, data: leanObject});
});
})
.catch(err => {
console.log(err);
});
},

Resources