MERN STACK image upload to MongoDB - node.js

hi can someone help me out im developing a MERN STACK APP with aws s3 i have 2 schema models one for user and one for images, im making a ref to the user inside my image schema, im successfully adding to MongoDB atlas the user with image, my issue is i want the user to be able to add the image in the existing array not a new one like its doing now and also how can i get all the data for the user thats logged in on the front end as off now im getting the same images for all users who log in.
-image schema-
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const imageSchema = new Schema(
{
user: {
type: Schema.Types.ObjectId,
ref: "User",
required: true,
},
image: {
type: [String],
default: "",
required: true,
},
},
{
timestamps: true,
}
);
module.exports = mongoose.model("PostImage", imageSchema);
-upload image-
const imageUploadS3 = (req, res, next) => {
const uploadSingle = upload("mern-stack-imageupload-insta").single("image");
uploadSingle(req, res, async (err) => {
if (err)
return res.status(400).json({ success: false, message: err.message });
console.log(req.file);
const imgDB = await PostImage.create({
user: req.userId,
image: req.file.location,
});
try {
await imgDB.save();
res.status(200).json({
success: true,
message: "image uploaded",
image: imgDB,
data: req.file.location,
});
} catch (error) {
res.status(500).json({ message: error.message });
}
});
};
getImage route
const getImages = async (req, res) => {
const { id } = req.userId;
try {
const image = await PostImage.findById(id);
if (!image) {
return res.status(404).json({ message: "Image not found" });
}
res.status(200).json(image);
} catch (error) {
res.status(409).json({ message: error.message });
}
};

Related

Im trying to update a users information using MongoDB and JWT

when I use this code to try and update the user it appears as a server error. Im using JWT and mongodb but am unsure if im pulling the token or the id to update the users information. Below my controller code is attached and my schema.
const updateUser = async (req, res) => {
try {
const user = await User.findByIdAndUpdate(req.user.id)
if(!user) return res.status(400).send({ error: 'User not found'})
Object.assign(user, req.body);
user.save()
res.send({ data: user})
} catch (error) {
res.status(500).send({error: 'Server Error'})
}
}
const mongoose = require('mongoose');
let userSchema = new mongoose.Schema({
name: { type: String, required: true},
email: { type: String, required: true, unique: true},
password: { type: String, required: true},
date: { type: Date, default: Date.now}
})
module.exports = mongoose.model('user', userSchema)
Updated update function but i appear to have an error
const updateUser = async (req, res) => {
try {
const updatedUser = await User.findByIdAndUpdate(req.params.id,req.body)
if(!updatedUser) return res.status(400).send('User cannot be updated!')
res.json(updatedUser)
} catch (error) {
res.status(500).send({error: 'Server Error'})
}
}
Try this :
//update user by id
exports.updateUser = async (req, res) => {
try {
const updatedUser = await
<--req.params.id is the user.id and req.body contains the requested fields to update -->
User.findByIdAndUpdate(req.params.id,req.body)
res.json(updatedUser);
}
catch (err) {
console.log(err);
res.status(500).json({ message: 'Internal server error' });
}
}

UnhandledPromiseRejectionWarning: ReferenceError: book is not defined

I stuck with a problem, when I hit my route addBook then getting an error like book is not defined don't know where I am please try to fix my code. if you have any query on my code please let me know.
route.js
This is the route.js file where I wrote my all logics
const express = require("express");
const router = express.Router();
const Publisher = require('../model/Categary');
const Book = require('../model/Product');
// const {addCatogary} = require('../controllers/Product');
// router.get('/addcatogary',addCatogary);
router.post("/addPublisher", async (req, res) => {
try {
//validate req.body data before saving
const publisher = new Publisher(req.body);
await publisher.save();
res.status(201).json({ success: true, data: publisher });
console.log(publisher);
} catch (err) {
res.status(400).json({ success: false, message: err.message });
}
console.log(err);
});
router.post("/addBook", async (req, res) => {
try {
//validate data as required
const book = new Book(req.body);
// book.publisher = publisher._id; <=== Assign user id from signed in publisher to publisher key
await book.save();
const publisher = await Publisher.findById({ _id: book.publisher });
publisher.publishedBooks.push(book);
await publisher.save();
//return new book object, after saving it to Publisher
res.status(200).json({ success: true, data: book });
} catch (err) {
res.status(400).json({ success: false, message: err.message });
}
console.log(book);
});
router.get("/publishers", async (req, res) => {
try {
const data = await Publisher.find().populate({
path: "booksPublished",
select: "name publishYear author",
});
res.status(200).json({ success: true, data });
} catch (err) {
res.status(400).json({ success: false, message: err.message });
}
console.log(data)
});
module.exports = router;
Product.js
const mongoose= require('mongoose');
const {Schema} = require('mongoose');
const bookSchema = new Schema({
name: String,
publishYear: Number,
author: String,
publisher: {
type: Schema.Types.ObjectId,
ref: 'Publisher',
required: true
}
},
{timestamps: true});
module.exports = mongoose.model('Book', bookSchema);
Catogary.js
This is the Catogary model.
const mongoose = require('mongoose');
const {Schema} = require('mongoose');
const publisherSchema = new Schema({
name: String,
location: String
},
{timestamps: true}
);
publisherSchema.virtual('booksPublished', {
ref: 'Book', //The Model to use
localField: '_id', //Find in Model, where localField
foreignField: 'publisher', // is equal to foreignField
});
// Set Object and Json property to true. Default is set to false
publisherSchema.set('toObject', { virtuals: true });
publisherSchema.set('toJSON', { virtuals: true });
module.exports = mongoose.model('Publisher', publisherSchema);
router.post("/addBook", async (req, res) => {
try {
//validate data as required
const book = new Book(req.body);
// book.publisher = publisher._id; <=== Assign user id from signed in publisher to publisher key
await book.save();
const publisher = await Publisher.findById({ _id: book.publisher });
publisher.publishedBooks.push(book);
await publisher.save();
//return new book object, after saving it to Publisher
res.status(200).json({ success: true, data: book });
} catch (err) {
res.status(400).json({ success: false, message: err.message });
}
console.log(book);
});
hey brother!
you have written a nice code but you have made a small mistake after catch block you are logging book which is defined inside try block and that book variable can not be accessed outside of that box because its local variable and can be only used inside try block
if you wanted to used that variable outside of try{} catch(){} block defined it with var
just check below link
geeksforgeeks.org/global-and-local-variables-in-javascript
happy hacking :)

Mongoose one-to-many not working (Nodejs)

I have created 2 Users(Admin and Users) and also i have created many ToDos for a User but here my Todo array is empty in my User Schema. Unable to understand why todo task are not assigned to the User Schema.
UserSchema
var userSchema = new Schema({
name: {
type: String,
required: true,
maxlength: 30,
trim: true
},
role: {
type: Number,
default: 0
},
todos: [{
type: Schema.Types.ObjectId,
ref:"Todo"
}]
});
module.exports = mongoose.model("User", userSchema)
Todo Schema
let Todo = new Schema({
todo_heading: {
type: String
},
todo_desc: {
type: String
},
todo_priority: {
type: String
},
todo_completed: {
type: Boolean
},
user: {
type: Schema.Types.ObjectId,
ref:"User"
}
})
module.exports = mongoose.model('Todo', Todo);
here are my routes
User Route
router.get("/user/:userId/todos", isSignedIn, isAuthenticated, getToDos)
Todo Route
router.get("/", getTodos)
router.get("/:id", getUsertodos);
router.post("/user/:userId/add", addUsertodos);
User Controllers
exports.getToDos = (req, res) => {
User.find({ _id: req.params._id })
.populate("todos")
.exec((err, toDo) => {
if (err) {
res.json(err)
}
res.json(toDo)
})
}
ToDo Controllers
exports.addUsertodos = (req, res) => {
let todo = new Todo(req.body)
todo.save((err, todo) => {
if (err) {
return res.status(400).json({
error: "not saved"
})
}
else {
return res.json(todo)
}
})
}
it should work as expected if you add the objectId of newly created todo to the todos property when you create a user.
//routers/todo.js
var express = require('express');
var router = express.Router();
const Todo = require('../models/Todo');
const User = require('../models/User');
/* GET home page. */
router.get('/', async function (req, res) {
let todos = await Todo.find();
res.json({
todos
});
});
router.post('/todos', async function (req, res) {
//add todos
let {
todo_desc,
todo_heading,
todo_priority,
todo_completed
} = req.body;
try {
//NOTE: for simplicity assigning first user but you can grab it from the params
let user = await User.findOne();
let todo = await Todo.create({
todo_desc,
todo_completed,
todo_priority,
todo_heading,
user: user._id
})
res.json({
message: 'todo created successfully',
todo
});
} catch (err) {
return res.status(500).json({
message: 'Unable to create a todo',
err: JSON.stringify(err)
})
}
});
module.exports = router;
Here is the user route where post route get the string id of created ID and converts it to ObjectId(), assign it to the todos.
var express = require('express');
var router = express.Router();
let _ = require('lodash');
var mongoose = require('mongoose');
const User = require('../models/User');
/* GET users listing. */
router.post("/", async function (req, res) {
let {
name,
todos
} = req.body;
try {
let user = new User();
user.name = name;
let objectIds = todos.split(',').map(id => mongoose.Types.ObjectId(id));
user.todos.push(...objectIds)
await user.save()
console.log("user: ", JSON.stringify(user));
if (_.isEmpty(user)) {
res.status(500).json({
message: 'unable to create user'
})
}
res.json(user);
} catch (err) {
res.status(500).json({
message: 'unable to create user',
err: JSON.stringify(err)
})
}
});
router.get("/", async function (req, res) {
try {
let user = await User.find().populate('todos');
console.log("user: ", JSON.stringify(user));
if (_.isEmpty(user)) {
res.status(500).json({
message: 'unable to find user'
})
}
res.json(user);
} catch (err) {
res.status(500).json({
message: 'unable to find user',
err: JSON.stringify(err)
})
}
});
module.exports = router;
Check out the attached screenshot, the user record now contains the todos assigned to it.
If you want checkout the working code, please visit this repo that i created!!.
Hope this help.Cheers!!

Getting cannot get error on Postman for all my API's

I am developing a backend project using nodejs, express and mongoose. But when I try to test my endpoints on Postman I keep getting this error. I am new to nodejs so I am not quite sure what this means.
This is my main js file index.js
const app = express();
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
require('dotenv/config');
const apiRoute = require('./routes/api');
const adminRoute = require('./routes/admin');
mongoose.Promise = global.Promise;
const port = process.env.PORT || 3000;
app.listen(port, () => console.log(`listening to port ${port}`));
app.use(bodyParser.json());
app.use('/api', apiRoute);
app.use('/admin', adminRoute);
// As per Mongoose Documentation
const options = {
useNewUrlParser: true,
useCreateIndex: true,
useFindAndModify: false,
useUnifiedTopology: true,
autoIndex: false, // Don't build indexes
//reconnectTries: Number.MAX_VALUE, // Never stop trying to reconnect
//reconnectInterval: 500, // Reconnect every 500ms
poolSize: 10, // Maintain up to 10 socket connections
// If not connected, return errors immediately rather than waiting for reconnect
bufferMaxEntries: 0,
connectTimeoutMS: 10000, // Give up initial connection after 10 seconds
socketTimeoutMS: 45000, // Close sockets after 45 seconds of inactivity
family: 4 // Use IPv4, skip trying IPv6
};
mongoose.connect('mongodb://localhost:27017/admin', options).then(
() => {
console.log('db connected');
},
(err) => {
console.log('connection error');
}
);
This is /routes/api.js
const router = express.Router();
const Ticket = require('../models/Ticket');
const Joi = require('joi');
const { seatValidation, typeValidation } = require('../validation');
//View all tickets
router.get('/tickets', async (req, res) => {
try {
let tickets = await Ticket.find();
res.json(tickets);
} catch (error) {
res.json({ message: error });
}
});
//View Ticket Status
router.get('/status/seat/:seat', async (req, res) => {
// input validation - seat should be a number and between 1-40
let { error } = seatValidation(req.params.seat);
if (error) return res.status(404).send(error);
try {
let status = await Ticket.findOne({ seat: parseInt(req.params.seat) }).select('status');
res.json(status);
} catch (error) {
res.json({ message: error });
}
});
//View Details of person owning the ticket
router.get('/details/seat/:seat', async (req, res) => {
// input validation - seat should be a number and between 1-40
let { error } = seatValidation(req.params.seat);
if (error) return res.status(404).send(error);
try {
let status = await Ticket.findOne({ seat: parseInt(req.params.seat) })
.select('status')
.select('first_name')
.select('last_name')
.select('gender')
.select('email')
.select('mobile');
res.json(status);
} catch (error) {
res.json({ message: error });
}
});
// adding empty seats
router.post('/add', async (req, res) => {
// input validation - seat should be a number and between 1-40
let { error } = seatValidation(req.body);
if (error) return res.status(404).send(error);
let ticket = new Ticket({
seat: req.body.seat,
status: 'open'
});
let ticketSaved = await ticket.save();
try {
res.json(ticketSaved);
} catch (error) {
res.json({ message: error });
}
});
//View all open tickets
router.get('/tickets/open', async (req, res) => {
try {
let tickets = await Ticket.find({ status: 'open' });
res.json(tickets);
} catch (error) {
res.json({ message: error });
}
});
//View all closed tickets
router.get('/tickets/closed', async (req, res) => {
try {
let tickets = await Ticket.find({ status: 'close' });
res.json(tickets);
} catch (error) {
res.json({ message: error });
}
});
//Update the ticket status (open/close + adding user details)
router.put('/status/:seat/:type', async (req, res) => {
// input validation - seat should be a number and between 1-40
let { seatError } = seatValidation(req.params.seat);
if (seatError) return res.status(404).send(seatError);
// input validation - type should be a string and should be 'open' or 'close'
let { typeError } = typeValidation(req.params.type);
if (typeError) return res.status(400).send(typeError);
try {
let type = req.params.type;
if (type === 'open') {
try {
let ticket = await Ticket.updateOne(
{ seat: req.params.seat },
{
$set: { status: 'open' },
$unset: { first_name: 1, last_name: 1, gender: 1, email: 1, mobile: 1 }
}
);
res.json(ticket);
} catch (error) {
res.json({ message: error });
}
} else if (type === 'close') {
// input validation - type should be a string and should be 'open' or 'close'
let ticketSchema = {
first_name: Joi.string().min(3).required(),
last_name: Joi.string().min(3).required(),
gender: Joi.string().valid('M').valid('F').valid('U').required(),
email: Joi.string().email().required(),
mobile: Joi.number().integer().min(1000000000).max(9999999999).required()
};
let validation = Joi.validate(req.body, ticketSchema);
if (validation.error) {
res.status(400).send(validation.error);
return;
}
try {
let ticket = await Ticket.updateOne(
{ seat: req.params.seat },
{
$set: {
status: 'close',
first_name: req.body.first_name,
last_name: req.body.last_name,
gender: req.body.gender,
email: req.body.email,
mobile: req.body.mobile
}
}
);
res.json(ticket);
} catch (error) {
res.json({ message: error });
}
}
} catch (error) {
res.json({ message: error });
}
});
module.exports = router;
This is schema /models/Ticket.js
const mongoose = require('mongoose');
const TicketSchema = mongoose.Schema({
seat: Number,
status: String,
first_name: String,
last_name: String,
gender: String,
email: String,
mobile: Number
});
module.exports = mongoose.model('Ticket', TicketSchema);
Can anyone help me out?
Here is the error from postman:
Postman screenshot
In your index.js file you have specified route for apiRoute as /api and in the screenshot, it appears that you have missed that.
Please use the URL as localhost:3000/api/tickets
instead of just localhost:3000/tickets and it should work correctly.
As you can see as you have missed the /api part the express does not have the path you requested and is returning the status of 404 not found.

Node.js API find a MongoDB Document by passing ObjectID

The following GET ALL route is working. The second route below, I am trying to retrieve a single Employee document by ObjectId. This is not working. Please help. My Employee model is at the bottom.
// Get all Employees
router.get("/", async (req, res) => {
try {
const employees = await Employee.find();
res.json(employees);
} catch (err) {
res.status(500).json({ message: err.message });
}
});
// Get Single Employee by ObjectId
router.get("/:id", (req, res) => {
try {
const employees = await Employee.find(id)
res.json(employees);
} catch (err) {
res.status(500).json({ message: err.message });
}
});
const employeeSchema = new mongoose.Schema({
_id: {
type: mongoose.Schema.Types.ObjectId,
required: true,
},
fname: {
type: String,
required: false,
},
lname: {
type: String,
required: false,
},
});
use findById(id) or find({_id: id})
https://mongoosejs.com/docs/api.html#model_Model.find

Resources