Unable to connect MongoDB in Node JS application - javascript

My application was running just fine and was connected to mongoDB while developing a simple node js application. But suddenly it started showing this error. Here is a snap of the console:
Here is my file providing mongoURI, and it was working just fine before the error:
module.exports = {
mongoURI:
"mongodb+srv://glorious:glorious#cluster0-to57n.mongodb.net/test?retryWrites=true&w=majority"
};
Here is my server.js file:
const express = require("express");
const mongoose = require("mongoose");
const app = express();
// DB Config
const db = require("./config/keys").mongoURI;
// Connect to MongoDB
mongoose
.connect(db)
.then(() => console.log("MongoDB Connected"))
.catch(err => console.log(err));
app.get("/", (req, res) => res.send("Hello World"));
const port = process.env.PORT || 5000;
app.listen(port, () => console.log(`Server running on port ${port}`));
And here is my package.json file:
{
"name": "devconnector",
"version": "1.0.0",
"description": "A social network for developers",
"main": "server.js",
"scripts": {
"start": "node server.js",
"server": "nodemon server.js"
},
"author": "Utkarsh Shrivastava",
"license": "ISC",
"dependencies": {
"bcryptjs": "^2.4.3",
"body-parser": "^1.19.0",
"express": "^4.17.1",
"gravatar": "^1.8.0",
"jsonwebtoken": "^8.5.1",
"mongoose": "^5.7.13",
"passport": "^0.4.0",
"passport-jwt": "^4.0.0",
"validator": "^12.1.0"
},
"devDependencies": {
"nodemon": "^2.0.1"
}
}

useNewUrlParser doc:
The useNewUrlParser Option
By default, mongoose.connect() will print out the below warning:
DeprecationWarning: current URL string parser is deprecated, and will
be removed in a future version. To use the new parser, pass option {
useNewUrlParser: true } to MongoClient.connect.
The MongoDB Node.js driver rewrote the tool it uses to parse MongoDB connection strings. Because this is such a big change, they put the new connection string parser behind a flag. To turn on this option, pass the useNewUrlParser option to mongoose.connect() or mongoose.createConnection().
mongoose.connect(uri, { useNewUrlParser: true });
mongoose.createConnection(uri, { useNewUrlParser: true });
You can also set the global useNewUrlParser option to turn on useNewUrlParser for every connection by default.
// Optional. Use this if you create a lot of connections and don't
want // to copy/paste `{ useNewUrlParser: true }`.
mongoose.set('useNewUrlParser', true);
To test your app with {useNewUrlParser: true }, you only need to check whether your app successfully connects. Once Mongoose has successfully connected, the URL parser is no longer important. If you can't connect with { useNewUrlParser: true }, please open an issue on GitHub.
useUnifiedTopology doc:
useUnifiedTopology
By default, mongoose.connect() will print out the below warning:
DeprecationWarning: current Server Discovery and Monitoring engine is
deprecated, and will be removed in a future version. To use the new
Server Discover and Monitoring engine, pass option {
useUnifiedTopology: true } to the MongoClient constructor.
Mongoose 5.7 uses MongoDB driver 3.3.x, which introduced a significant refactor of how it handles monitoring all the servers in a replica set or
sharded cluster. In MongoDB parlance, this is known as server
discovery and monitoring.
To opt in to using the new topology engine, use the below line:
mongoose.set('useUnifiedTopology', true);
If you find any unexpected
behavior, please open up an issue on GitHub.
So you need to pass both options to mongoose.connect:
// Connect to MongoDB
mongoose
.connect(db, { useNewUrlParser: true, useUnifiedTopology: true })
...

your server.js file
const express = require('express');
const connectDB = require('./config/db');
const app = express();
// connect Database
connectDB();
app.get('/', (req, res) => res.send('API Running...'));
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => console.log(`Server Started On Port ${PORT}`));
db.js file under config folder
const mongoose = require('mongoose');
const config = require('config');
const db = config.get('mongoURI');
const connectDB = async () => {
try {
await mongoose.connect(db, {
useNewUrlParser: true,
useUnifiedTopology: true
});
console.log('MongoDB Connected !!');
} catch (err) {
console.error(err.message);
// Exit process
process.exit(1);
}
};
module.exports = connectDB;
default.json under config folder
{
"mongoURI": mongodb://[username:password#]host1[:port1][,...hostN[:portN]][/[database][?options]]
}
you can check more on
Connection String URI Format for default.json

You are missing URL PARSER.
Just modify your code to
...rest of the code
// Connect to MongoDB
mongoose
.connect(db, {newUrlParser: true})
.then(() => console.log("MongoDB Connected"))
.catch(err => console.log(err));
...rest of the code
Or you can also set it globally using
mongoose.set('useNewUrlParser', true);
Read more about it here
https://mongoosejs.com/docs/deprecations.html

I have Just Worked with Mondo DB.
This code may helps
add {useNewUrlParser:true} while connecting to MongoDb.see Mongo DB deprecations
your server.js file:
const express = require("express");
const mongoose = require("mongoose");
const app = express();
// DB Config
const db = require("./config/keys").mongoURI;
// Connect to MongoDB
mongoose
.connect(db, { useNewUrlParser: true })
.then(() => console.log("MongoDB Connected"))
.catch(err => console.log(err));
app.get("/", (req, res) => res.send("Hello World"));
const port = process.env.PORT || 5000;
app.listen(port, () => console.log(`Server running on port ${port}`));
Hope this work fine, and will connect you mongo db.

Related

How to work on a hosted Website and make changes?

So I have a full stack website and the frond end is hosted on netlify via github and the backend is hosted on heroku. When I make changes on front end I have to push each change to github in order to see the result. I am a newbie and I do not know how should I work on a project locally when all my routes are netlify and heroku routes.
This is the code
const express = require("express");
const path = require("path");
const mongoose = require("mongoose");
const dotenv = require("dotenv");
const cookieParser = require("cookie-parser");
const cors = require("cors");
const User = require("./models/userModel");
dotenv.config();
// set up server
const app = express();
app.listen(process.env.PORT || 5000, () =>
console.log(`Server started on port: ${process.env.PORT || 5000 }`)
);
app.get("/test", (req, res) => {
res.send("It works");
});
app.use(express.json());
app.use(cookieParser());
app.use(
cors({
origin: "https://awesome-murdock-.netlify.app/",
credentials: true,
})
);
// connect to mongoDB
mongoose.connect(
process.env.MONGODB_URI,
{
useNewUrlParser: true,
useUnifiedTopology: true,
},
(err) => {
if (err) return console.error(err);
console.log("Connected to MongoDB");
}
);
// sign
// set up routes
app.use("/auth", require("./routers/userRouter"));
app.use("/customer", require("./routers/customerRouter"));
app.get('/', (req, res) => {
res.send('Hi')
})
as you can see cors is ponting to my netlify app and it has not connection with my back end and the same is with backend

Getting an error while connecting MongoDB: The `uri` parameter to `openUri()` must be a string

I want to connect my database using .env file but I am getting an error:
I tried console logging my .env variable but I am getting Undefined:
Here are my scripts:
server.js
require("dotenv").config({ path: "./config.env" });
const express = require("express");
const app = express();
const connectDB = require("./config/db");
// Connect DB
connectDB();
app.use(express.json());
app.use("/api/auth", require("./routes/auth"));
const PORT = process.env.PORT || 5000;
const server = app.listen(PORT, () =>
console.log(`Sever running on port ${PORT}`)
);
console.log("```` DB NAME ````", process.env.DATABASE_CONNECTION);
process.on("unhandledRejection", (err, promise) => {
console.log(`Logged Error: ${err.message}`);
server.close(() => process.exit(1));
});
db.js
const mongoose = require("mongoose");
const connectDB = async () => {
await mongoose.connect(process.env.DATABASE_CONNECTION, {
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true,
useFindAndModify: true,
});
console.log("MongoDB Connected");
};
module.exports = connectDB;
config.env
PORT=5000
DATABASE_CONNECTION=mongodb://localhost:27017/node_auth
I have checked other solutions, but none of them helped.
This solved my issue:
require("dotenv").config({
path:
"C:/Users/.../auth/config.env",
});
Basically, write whole path of the file.

ReferenceError: require is not defined using require("dotenv").config();

For some reason i am having this error "ReferenceError: require is not defined" and i cant figure out why ?. Has anyone got an idea how i can fix this ? i am trying to connect my e-commerce website to mongodb
here's the code
.env file
PORT=5000
MONGO_URL = mongodb+srv://nashmaj:frzw14qa#cluster0.52b6h.mongodb.net/e-commerce-webapp?retryWrites=true&w=majority
server.js file
require("dotenv").config();
const express = require('express')
const app = express();
const mongoose = require('mongoose')
const cors = require('cors')
const fileUpload = require('express-fileupload')
const cookieParser = require('cookie-parser');
// const { Console } = require('console');
const PORT = process.env.PORT || 5000
app.use(express.json())
app.use(cookieParser())
app.use(cors)
app.use(fileUpload({
useTempFiles: true
}))
//connect to db
const URL = process.env.MONGO_URL
mongoose.connect({
useCreateIndex: true,
useFindAndModify: false,
useUnifiedTopology:true
}, err=> {
if (err) throw err;
console.log('Connected to Mongo DB')
})
app.get('/', (req, res) => {
res.json({msg: "Welcome"})
})
app.listen(PORT, () => {
console.log('Server is running on port', PORT)
})
You can check if you have configured node to use ES Modules. This is in package.json
"type": "module",
Remove this line and check again.
Remember that having "type": "module"you cannot use require and instead you need to use import syntax.

Why does this Node app hangs when saving to MongoDB?

These codes work perfectly locally and there is data saved to MongoDB and I could pull data from it. However when it is deployed to Heroku, the app hangs at the '.save()' portion. Needless, nothing is saved to MongoDB.
Am I doing anything wrong? Could it be the .env portion?
(Works on repl.it and glitch too but not locally from Visual Studio Code)
Full codes at github if anyone wants to take a peek
urlshortener.html
<form action="api/shorturl/new" method="POST">
<label for="url_input">URL to be shortened</label>
<input id="url_input" type="text" name="url" value="https://www.freecodecamp.org">
<input type="submit" value="POST URL">
</form>
package.json
"dependencies": {
"body-parser": "^1.19.0",
"cors": "^2.8.0",
"dotenv": "^8.2.0",
"ejs": "^2.5.6",
"express": "^4.15.2",
"heroku": "^7.43.2",
"mongodb": "^3.6.2",
"mongoose": "^5.10.7",
"shortid": "^2.2.15"
server.js
// init project
require('dotenv').config();
var express = require('express');
var mongodb = require('mongodb');
var mongoose = require('mongoose');
var bodyParser = require('body-parser');
var shortid = require('shortid');
var app = express();
var port = process.env.PORT || 3000
let uri = process.env.MONGODB_URI;
mongoose.connect(uri, {
useNewUrlParser: true,
useUnifiedTopology: true
});
var cors = require('cors');
app.use(cors({ optionsSuccessStatus: 200 })); // some legacy browsers choke on 204
// http://expressjs.com/en/starter/static-files.html
app.use(express.static('public'));
// http://expressjs.com/en/starter/basic-routing.html
app.get("/", function (req, res) {
res.sendFile(__dirname + '/views/index.html');
});
app.get("/urlshortener", function (req, res) {
res.sendFile(__dirname + '/views/urlshortener.html');
});
// testing API endpoint...
app.get("/api/hello", function (req, res) {
res.json({ greeting: 'hello API' });
});
// URL Shortener Microservice
// define the schema and build a model to store saved urls
let ShortUrl = mongoose.model('HerokuUrl', new mongoose.Schema({
original_url: String,
short_url: String,
suffix: String
}));
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
app.post("/api/shorturl/new", (req, res) => {
let client_requested_url = req.body.url; // from input box
let suffix = shortid.generate(); // automatically generated
// this works
// res.json({
// 1: client_requested_url,
// 2: suffix
// })
let newUrl = new ShortUrl({
original_url: client_requested_url,
// short_url: client_requested_url + "/api/shorturl/" + suffix,
short_url: __dirname + "/api/shorturl/" + suffix,
suffix: suffix // suffix: suffix
})
// this works
// res.json({
// 'info': newUrl
// })
// APP HANGS at this save
newUrl.save((err, doc) => {
if (err) return console.error(err);
res.json({
original_url: newUrl.original_url,
short_url: newUrl.short_url,
suffix: newUrl.suffix // suffix: suffix
});
});
});
app.get("/api/shorturl/:suffix", (req, res) => {
let urlSuffix = req.params.suffix;
ShortUrl.findOne({ suffix: urlSuffix }).then(foundUrl => {
res.redirect(foundUrl.original_url);
});
})
// listen for requests
var listener = app.listen(port, function () {
console.log('Your app is listening on port ' + listener.address().port);
});
I got it working...
The app hangs at .save() so it has something got to do with the database.
It works locally but not when I push to heroku, so it has something got to do with the environment variable.
I typed heroku logs --tail and logged the environment variable which got undefined and this:
UnhandledPromiseRejectionWarning: MongooseError: The `uri` parameter to `openUri()` must be a string, got "undefined". Make sure the first parameter to `mongoose.connect()` or `mongoose.createConnection()` is a string.
So I snooped around Stackoverflow and added the database uri as a config variable in Heroku.
It worked!!!!
Thanks everyone.
Try using mongo db atlas for network storage

Express Router.Post not sending back Json on Postman

I am attempting to learn express and how to use postman and I'm following along a tutorial. Everything was going well until I tested router.get by sending dummy data to the server. I use postman to attempt to post to my localhost 500. Instead of getting a json back of the data in which I sent, I get a 200 status and nothing at the bottom of my screen. When i check the console upon hitting that route, this is logged to the console: http://undefined/api/members.
Mind you, I have no trouble using router.get to receive a json of all my members and I have no trouble receiving a json by searching with just the member ID. But for whatever reason router.post isn't working for me. I suspect this has to do with the body parser. But I'm not sure why specifically it isn't working. Please help.
This is how I set up my app file:
const express = require('express')
const app = express()
const path = require('path');
const logger = require('./middleware/logger')
const bodyParser = require('body-parser')
app.use(logger)
app.use('/api/members', require('./routes/api/members'))
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({extended: false}))
app.use(express.static(path.join(__dirname, 'public')))
const PORT = process.env.PORT || 5000
app.listen(PORT, () => {
console.log(`Server started on port ${[PORT]}`)
})
The following is how I set up my router file
const express = require('express')
const router = express.Router()
const members = require('../../Members')
router.get('/', (req, res) =>{
res.json(members);
})
router.get('/:id', (req, res) => {
const found = members.some(member => member.id === parseInt(req.params.id));
if(found){
res.json(members.filter(member => member.id === parseInt(req.params.id)))
} else {
res.status(400).json({msg: `No member with the id of ${req.params.id}`})
}
})
router.post('/', (req, res) => {
res.send(req.body)
})
module.exports = router
my package.json:
{
"name": "expressCrashCourse",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node index",
"dev": "nodemon index"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"body-parser": "^1.19.0",
"express": "^4.17.1",
"moment": "^2.24.0"
},
"devDependencies": {
"nodemon": "^2.0.2"
}
}
Routes are processed in order so if you want the body-parser middleware to be active for your .post() route, the middleware has to be BEFORE it. So, change this:
app.use('/api/members', require('./routes/api/members'))
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({extended: false}))
to this:
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({extended: false}))
app.use('/api/members', require('./routes/api/members')) // <== after your middleware
As it was, it was hitting your route before the middleware got a chance to run and thus req.body was still not populated with the body contents.

Categories