How to connect to mongodb via mongoose in nodejs - reactjs

controller/product.controller.js this is the controller class
const Product = require('../models/product.model');
//Simple version, without validation or sanitation
exports.test = function (req, res) {
res.send('Greetings from the Test controller!');
};
exports.product_create = function (req, res) {
const product = new Product(
{
name: req.body.name,
price: req.body.price
}
);
product.save(function (err) {
if (err) {
return next(err);
}
res.send('Product Created successfully')
})
};
models/product.model.js
var mongoose = require('mongoose');
const Schema = mongoose.Schema;
const ProductSchema = new Schema({
name: {type: String, required: true, max: 100},
price: {type: Number, required: true},
});
exports.product_details = function (req, res) {
Product.findById(req.params.id, function (err, product) {
if (err) return next(err);
res.send(product);
})
};
exports.product_delete = function (req, res) {
Product.findByIdAndRemove(req.params.id, function (err) {
if (err) return next(err);
res.send('Deleted successfully!');
})
};
exports.product_update = function (req, res) {
Product.findByIdAndUpdate(req.params.id, {$set: req.body}, function (err, product) {
if (err) return next(err);
res.send('Product udpated.');
});
};
router.put('/:id/update', product_controller.product_update);
// Export the model
module.exports = mongoose.model('Product', ProductSchema);
product.route.js this is used to route
const express = require('express');
const router = express.Router();
// Require the controllers WHICH WE DID NOT CREATE YET!!
const product_controller = require('../controllers/product.controller');
router.post('/create', product_controller.product_create);
// a simple test url to check that all of our files are communicating correctly.
router.get('/test', product_controller.test);
router.put('/:id/update', product_controller.product_update);
router.delete('/:id/delete', product_controller.product_delete);
module.exports = router;
app.js this is the app.js
const express = require('express');
const bodyParser = require('body-parser');
const product = require('./routes/product.route'); // Imports routes for the products
const app = express();
// Set up mongoose connection on mongoAtlas
//https://codeburst.io/writing-a-crud-app-with-node-js-and-mongodb-e0827cbbdafb
const mongoose = require('mongoose');
const dev_db_url = 'mongodb://someuser:abcd1234#ds123619.mlab.com:23619/productstutorial';
const mongoDB = process.env.MONGODB_URI || dev_db_url;
mongoose.connect(mongoDB);
mongoose.Promise = global.Promise;
const db = mongoose.connection;
db.on('error', console.error.bind(console, 'MongoDB connection error:'));
app.use('/products', product);
app.listen(3000,function () {
console.log("Server listen on port: 3000");
});
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use('/products', product);
So this is the code of the project and please add scripts "start": "node app.js". This will directly be able to use this and update,insert and delete data is also given here with the code.

The setup looks good, However I noticed few points you might missed in app.js. I believe the following slightly modified setup will connect your mongodb properly:
const mongoose = require('mongoose');
const express = require('express');
var cors = require('cors');
const bodyParser = require('body-parser');
const product = require('./routes/product.route'); // Imports routes for the products
const API_PORT = 3000;
const app = express();
app.use(cors());
// Set up mongoose connection on mongoAtlas
//https://codeburst.io/writing-a-crud-app-with-node-js-and-mongodb-e0827cbbdafb
const dev_db_url = 'mongodb://someuser:abcd1234#ds123619.mlab.com:23619/productstutorial';
// connects our back end code with the database
mongoose.connect(process.env.MONGODB_URI || dev_db_url, { useNewUrlParser: true });
let db = mongoose.connection;
db.once('open', () => console.log('connected to the database'));
// checks if connection with the database is successful
db.on('error', console.error.bind(console, 'MongoDB connection error:'));
// bodyParser, parses the request body to be a readable json format
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
// append /api for our http requests
app.use('/product', product);
// launch our backend into a port
app.listen(API_PORT, () => console.log(`LISTENING ON PORT ${API_PORT}`));

mongoose.connect(url, (err) => {
if (!err) {
app.listen(PORT, () => {
console.log('SERVER WORKING');
})
}
})

Related

Error while Inserting Data through Thunderclient into MONGODB

I'm new in using MERN Stack & I'm trying to connect Mongo and Node but facing this issue while inserting Data into Database, using MongoDb Compass
Index.js
const connectToMongo = require('./db');
const express = require('express')
connectToMongo();
const app = express()
const port = 3000
app.use(express.json())
//Available Routes
app.use('/api/auth', require('./routes/auth'))
app.use('/api/auth', require('./routes/notes'))
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})
User.js
const mongoose = require('mongoose');
const { Schema } = mongoose;
const UserSchema = new Schema({
name:{
type: String,
require: true
},
email:{
type:String,
require:true,
unique: true
},
password:{
type:String,
require:true
},
timestamp:{
type:Date,
default:Date.now
}
});
module.exports = mongoose.model('user', UserSchema)
auth.js
const express=require('express');
const User = require('../models/User');
const router=express.Router()
router.get('/', (req, res)=>{
console.log(req.body)
const user = User(req.body)
user.save()
res.send(req.body)
})
module.exports = router
db.js
const mongoose = require('mongoose')
const mongoURI = "mongodb://localhost:27017/"
const connectToMongo=()=>{
mongoose.set("strictQuery", false);
mongoose.connect(mongoURI,()=>{
console.log("Connected to Mongo Successfully")
})
}
module.exports = connectToMongo;
ThunderClient Request:
{
"name":"pratik",
"email":"pratik#mail.com",
"password":"6626"
}
Error:
const err = new MongooseError(message);
^
MongooseError: Operation users.insertOne() buffering timed out after 10000ms
at Timeout. (D:\Study\React\MERN\inotebook\backend\node_modules\mongoose\lib\drivers\node-mongodb-native\collection.js:175:23)
at listOnTimeout (node:internal/timers:564:17)
at process.processTimers (node:internal/timers:507:7)
I guess the problem is because of the newer version, I'm trying to read the Docs and StackOverFlow but unable to Solve this Error what should I Do
You get the error because you are not connected to mongo actually.
You miss async/await in db.js
const connectToMongo = async () => {
mongoose.set("strictQuery", false);
await mongoose.connect(mongoURI,
// you can add this opts
{ keepAlive: true,
useNewUrlParser: true,
useUnifiedTopology: true,
})
console.log("Connected to Mongo Successfully")
}
And also later when you are calling user.save() it also should be async:
async (req, res)=>{
console.log(req.body)
const user = User(req.body)
await user.save()
res.send(req.body)
Thanks Everyone
the Solution was quite simple,
Just Change your localhost to 127.0.0.1:270

Postgres API returning html instead of json

I have a React app running Express querying a remote Postgres instance. I've set up some API routes to return data. When running locally, the data is returned as application/json, however when deployed to EC2 the same queries are returned as text/html so I cannot access it.
Here's some of the server code
require("dotenv").config();
const express = require("express");
const cors = require("cors");
const axios = require("axios");
const config = require("./config");
const path = require("path");
const db = require("./db");
const PORT = process.env.PORT || 8080;
const bodyParser = require("body-parser");
const app = express();
const pdf = require('html-pdf');
const pdfTemplate = require('./documents');
// CORS is to allow access on different domains
app.use(cors());
// parse application/json
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.use(express.static(path.join(__dirname, "client", "build")));
// TEST ROUTE
app.get("/api", (req, res) => {
res.json({ message: "Hello from server!" });
});
// ALL USERS
app.get("/api/v1", async (req, res) => {
try {
const usersOutput = await db.query(
"select * from users"
);
res.status(200).json({
status: "success",
results: usersOutput.rows.length,
data: {
users: usersOutput.rows,
},
});
} catch (err) {
console.log(err);
}
});
// SINGLE USER
app.get("/api/v1/:id", async (req, res) => {
try {
const userDetailOutput = await db.query(
"select col1, col2 from details psl inner join users pu on psl.user_id = pu.id where pu.auth0_id = $1", [req.params.id]
);
res.status(200).json({
status: "success",
data: {
user_details: userDetailOutput.rows,
},
});
} catch (err) {
console.log(err);
}
});

change code from template engine to next js

How do I convert my app that is made with .pug to next app ? I have an app using .pug engine and I want to convert it into next.
This is the app.js but as I know next is different how do I do it? Because here my files are in views, and in views the files are in pages etc how do I do it? Is there any way or I have to code it all again?
const express = require('express');
const app = express();
const port = process.env.PORT || 3000;
const middleware = require('./middleware')
const path = require('path')
const bodyParser = require("body-parser")
const mongoose = require("./database");
const session = require("express-session");
const http = require('http');
const server = app.listen(port, () => console.log("Server listening on port " + port));
const io = require("socket.io")(server, { pingTimeout: 60000 });
app.set("view engine", "pug");
app.set("views", "views");
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, "public")));
app.use(session({
secret: "#########",
resave: true,
saveUninitialized: false
}))
// Routes
const loginRoute = require('./routes/loginRoutes');
const registerRoute = require('./routes/registerRoutes');
const logoutRoute = require('./routes/logout');
const postRoute = require('./routes/postRoutes');
const profileRoute = require('./routes/profileRoutes');
const uploadRoute = require('./routes/uploadRoutes');
const searchRoute = require('./routes/searchRoutes');
const messagesRoute = require('./routes/messagesRoutes');
const notificationsRoute = require('./routes/notificationRoutes');
// Api routes
const postsApiRoute = require('./routes/api/posts');
const usersApiRoute = require('./routes/api/users');
const chatsApiRoute = require('./routes/api/chats');
const messagesApiRoute = require('./routes/api/messages');
const notificationsApiRoute = require('./routes/api/notifications');
app.use("/login", loginRoute);
app.use("/register", registerRoute);
app.use("/logout", logoutRoute);
app.use("/posts", middleware.requireLogin, postRoute);
app.use("/profile", middleware.requireLogin, profileRoute);
app.use("/uploads", uploadRoute);
app.use("/search", middleware.requireLogin, searchRoute);
app.use("/messages", middleware.requireLogin, messagesRoute);
app.use("/notifications", middleware.requireLogin, notificationsRoute);
app.use("/api/posts", postsApiRoute);
app.use("/api/users", usersApiRoute);
app.use("/api/chats", chatsApiRoute);
app.use("/api/messages", messagesApiRoute);
app.use("/api/notifications", notificationsApiRoute);
app.get("/", middleware.requireLogin, (req, res, next) => {
var payload = {
pageTitle: "Home",
userLoggedIn: req.session.user,
userLoggedInJs: JSON.stringify(req.session.user),
}
res.status(200).render("home", payload);
})
io.on("connection", socket => {
socket.on("setup", userData => {
socket.join(userData._id);
socket.emit("connected");
})
socket.on("join room", room => socket.join(room));
socket.on("typing", room => socket.in(room).emit("typing"));
socket.on("stop typing", room => socket.in(room).emit("stop typing"));
socket.on("notification received", room => socket.in(room).emit("notification received"));
socket.on("new message", newMessage => {
var chat = newMessage.chat;
if(!chat.users) return console.log("Chat.users not defined");
chat.users.forEach(user => {
if(user._id == newMessage.sender._id) return;
socket.in(user._id).emit("message received", newMessage);
})
});
})
If you don't want to refactor all your pug template engine pages to next.js pages, then you can make the pug pages coexist with the next.js. You can make the next.js the default route, and place next.js code after all pug page routes. And you also need to refactor app.get("/", middleware.requireLogin, (req, res, next) => {...} to make sure next.js is the default route.
To apply this rule, you need a custom next.js server.
sample code
const express = require('express');
const next = require('next');
const port = 3000;
const dev = process.env.NODE_ENV !== 'production'; // use default NodeJS environment variable to figure out dev mode
const app = next({dev, conf});
const handle = app.getRequestHandler();
const server = express();
// all your pug page routes should be declared before `server.get('*'`.
server.get('*', authMiddleware(false), (req, res) => {
// pass through everything to NextJS
return handle(req, res);
});
app.prepare().then(() => {
server.listen(port, (err) => {
if (err) throw err;
console.log('NextJS is ready on http://localhost:' + port);
});
}).catch(e => {
console.error(e.stack);
process.exit(1);
});

How to Get Param Id from URL in express/mongo/mongoose on server side, axios/react/redux on client side

I am having some trouble with get the param from the url. I use Express(4.16.3) on the server side, and using Axios to make the request. But I couldn't seem to get the param from the url in Express.
Here is my code:
on my Route.js in Express
app.get('/api/surveys/:surveyId', (req, res, next) => {
var id = req.params.surveyId;
console.log(req.params);
// it gets params {surveyId: ':surverId'}
res.send('Hello World');
});
so instead of getting the actual id, it logs params: {surveyId: ':surveyId'}. I have been researching, but seems this is the correct way to do it. I also use axios to make the request:
in actions/index.js (I use react):
export const fetchOneSurvey = () => async dispatch => {
const res = await axios.get('/api/surveys/:surveyId');
dispatch({ type: FETCH_ONE_SURVEY, payload: res.data });};
Not sure if this is relevant:
On the view page, instead of having http://localhost:3000/api/surveys/:surveyId, I have http://localhost:3000/surveys/:surveyId route set in React. When I go to http://localhost:3000/surveys/:surveyId, it does console log (req.params) like I write in express, but I only get a string ':surveyId' is the params, not the actual id on the url.
Please anyone can help me? I have tried many different ways, but nothing seem working. I thank you all very much in advance.
===== Extra section ======
Here is my index.js:
const express = require('express');
const mongoose = require('mongoose');
const cookieSession = require('cookie-session');
const passport = require('passport');
const bodyParser = require('body-parser');
const keys = require('./config/keys');
require('./models/User');
require('./models/Survey');
require('./services/passport');
mongoose.connect(keys.mongoURI);
const app = express();
app.use(bodyParser.json());
app.use(
cookieSession({
maxAge: 30 * 24 * 60 * 60 * 1000,
keys: [keys.cookieKey]
})
);
app.use(passport.initialize());
app.use(passport.session());
require('./routes/authRoutes')(app);
require('./routes/billingRoutes')(app);
require('./routes/surveyRoutes')(app);
if (process.env.NODE_ENV === 'production') {
app.use(express.static('client/build'));
const path = require('path');
app.get('*', (req, res) => {
res.sendFile(path.resolve(__dirname, 'client', 'build', 'index.html'));
});
}
My survey model route js:
const _ = require('lodash');
const Path = require('path-parser');
const { URL } = require('url');
const mongoose = require('mongoose');
const requireLogin = require('../middlewares/requireLogin');
const requireCredits = require('../middlewares/requireCredits');
const Mailer = require('../services/Mailer');
const surveyTemplate = require('../services/emailTemplates/surveyTemplate');
const Survey = mongoose.model('surveys');
module.exports = app => {
app.get('/api/surveys', requireLogin, async (req, res) => {
const surveys = await Survey.find({ _user: req.user.id }).select({
recipients: false
});
res.send(surveys);
});
app.get('/api/surveys/:surveyId/:choice', (req, res) => {
res.send('thanks for voting');
});
app.get('/api/surveys/:surveyId', (req, res, next) => {
var id = req.params.surveyId;
console.log(id);
// it gets params {surveyId: ':surverId'}
res.send('Hello World');
});
app.post('/api/surveys/webhooks', (req, res) => {
// console.log(req.body);
// res.send({});
const p = new Path('/api/surveys/:surveyId/:choice');
const test = _.chain(req.body)
.map(({ email, url }) => {
const match = p.test(new URL(url).pathname);
if (match) {
return {
email,
surveyId: match.surveyId,
choice: match.choice
};
}
})
.compact()
.uniqBy('email', 'surveyId')
.each(({ surveyId, email, choice }) => {
Survey.updateOne(
{
// have to add _ to keys as mongoDB rule, mongoose doensn't need.
_id: surveyId,
recipients: {
$elemMatch: { email: email, responded: false }
}
},
{
$inc: { [choice]: 1 },
$set: { 'recipients.$.responded': true },
lastResponded: new Date()
}
).exec();
})
.value();
console.log(test);
res.send({});
});
app.post('/api/surveys', requireLogin, requireCredits, async (req, res) => {
const { title, subject, body, recipients } = req.body;
const survey = new Survey({
// map(email => ({ email }) === map(email =>{ return {email: email}})
title,
body,
subject,
recipients: recipients
.split(',')
.map(email => ({ email: email.trim() })),
_user: req.user.id,
dateSent: Date.now()
});
// send an email
const mailer = new Mailer(survey, surveyTemplate(survey));
try {
await mailer.send();
await survey.save();
req.user.credits -= 1;
const user = await req.user.save();
res.send(user);
} catch (err) {
res.status(422).send(err);
}
});
};
Posting below details for debugging the issue
Note: if you are using Windows OS, use command prompt for node project development. i have seen people using git bash for doing node project developments and it causes unnecessary issues
Below are the steps for debugging
1.Create a new directoryforexample test and initialize it using npm init
2.Install express npm install --save express
3.Create a new file for example index.js and use below code
test/index.js
var express= require("express");
var app = express();
app.get("/api/surveys/:surveyId",(req,res,next)=>{
console.log(req.params.surveyId);
res.send('Hello World');
});
var server= app.listen(3000,()=>{
console.log("port started at ",server.address().port);
})
4.Start the program node index.js
5.Trigger http request from browser http://localhost:3000/api/surveys/llads . The value llads can be accessed using the path param surveyId in the route
6.if you can see the below output in node console then the program is working as it should. And this has to work as described here.
if above steps yields expected output then i don't see any problem in your route code.
Let me know your feedback.

MEAN: TypeError: ... is not a constructor

I'm very new to development and working my way through this MEAN tutorial:
MEAN Stack Front To Back [Part 3] - User Model & Register
I've read a few questions on here but can't find a relevant answer.
Here is the primary error code:
Server started on port 3000
Database Error MongoError: failed to connect to server [localhost:27017]
on first connect
TypeError: User is not a constructor
at router.post (/Users/user/Desktop/Development/meanauthapp/routes/users.js:12:16)
Which is odd, because my mongod terminal states this:
2017-03-15T09:52:49.306-0700 I NETWORK
[thread1] waiting for connections on port 27017
2017-03-15T09:52:54.514-0700 I NETWORK
[thread1] connection accepted from 127.0.0.1:49188 #1 (1 connection now open)
2017-03-15T09:52:54.515-0700 I NETWORK
[conn1] received client metadata from 127.0.0.1:49188 conn1:
{ application: { name: "MongoDB Shell" },
driver: { name: "MongoDB Internal Client", version: "3.4.1" },
os: { type: "Darwin", name: "Mac OS X", architecture: "x86_64", version: "15.6.0" } }
/routes/users.js
/*---------------Dependencies-------------*/
const express = require('express');
const router = express.Router();
const User = require('../config/database');
const passport = require('passport')
const jwt = require('jsonwebtoken');
/*----------------------------------------*/
/*---------------Register-----------------*/
router.post('/register', (req, res, next) => {
let newUser = new User({
name: req.body.name,
email: req.body.email,
username: req.body.username,
password: req.body.password
});
User.addUser(newUser, (err, user) => {
if(err) {
res.json({success: false, msg:'Failed to register user'});
} else {
res.json({success: true, msg: 'User Registered'})
}
});
});
/*----------------------------------------*/
/*---------------Authenticate---------------*/
router.post('/authenticate', (req, res, next) => {
res.send('AUTHENTICATE')
});
/*----------------------------------------*/
/*-----------------Profile------------------*/
router.get('/profile', (req, res, next) => {
res.send('PROFILE')
});
/*----------------------------------------*/
module.exports = router;
The line with error is : let newUser = new User({
/config/database.js
module.exports = { database: "mongodb://localhost:27017/famjam",
secret : "yoursecret" }
/models/users.js
const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');
const config = require('../models/database');
/*User Scheme*/
const UserScheme = mongoose.Scheme({
name: {
type: String
},
email: {
type: String,
required: true
},
username: {
type: String,
required: true
},
password: {
type: String,
required: true
}
});
const User = module.exports = mongoose.model('User', UserScheme);
module.exports.getUserById = function(id, callback) {
User.findById(id, callback);
}
module.exports.getUserbyUsername = function(username, callback) {
const query = {username: username}
User.findOne(query, callback);
}
module.exports.addUser = function(newUser, callback) {
bcrypt.genSalt(10, (err, salt) => {
bcrypt.hash(newUser.password, salt, (err, hash) => {
if(err) throw err;
newUser.password = hash;
newUser.save(callback);
})
});
}
app.js
/*---------------Dependencies-------------*/
const express = require('express');
const path = require('path');
const bodyParser = require('body-parser');
const cors = require('cors');
const passport = require('passport');
const mongoose = require('mongoose');
const users = require('./routes/users')
const config = require('./config/database')
/*----------------------------------------*/
/*---------------Database-------------*/
mongoose.connect(config.database);
mongoose.connection.on('connected', () => {
console.log('connected to database ' +config.database)
});
mongoose.connection.on('error', (err) => {
console.log('Database Error '+err)
});
/*----------------------------------------*/
/*------------------App-------------------*/
const app = express();
// Port Number
const port = 3000;
app.listen(port, () => {
console.log('Server started on port '+port)
});
//CORS Middleware
app.use(cors());
// Body Parser Middelware
app.use(bodyParser.json())
// Set Static Folder
app.use(express.static(path.join(__dirname, 'public')));
app.use('/users', users)
/*----------------------------------------*/
/*---------------Index Route--------------*/
app.get('/', (req, res) => {
res.send('Invalid Endpoint')
});
app.get('/myaccount', (req,res) =>{
res.render('myaccount')
})
If your req.body is an object having name, email, username and password set, you should be able to create a new User simply doing:
let newUser = new User(req.body);
You get this error since you are passing to the constructor an object having 4 different attributes, while it expect to receive a request body.

Resources