I'm trying to connect MongoDB Atlas to my application and ran into this error when trying to run the mongoose.connect(), which is located in db.js (last code in the question). process.env.MONGO_URI seems to be interpreted as undefined and not string, giving the following error: "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."
this is the my config.env, in which I copy pasted the MONGO_URI from the Atlas.
MONGO_URI = mongodb+srv://kpae:XXXX#practice.xujsvaf.mongodb.net/?retryWrites=true&w=majority
this is app.js, where I believe I set up the basics to run the program.
const express = require('express')
const dotenv = require('dotenv')
const connectDB = require('./config/db')
dotenv.config({ path: '.config/config.env' })
connectDB()
const app = express()
const PORT = process.env.PORT || 5000
app.listen(
PORT,
console.log(`Server running in ${process.env.NODE_ENV} mode on port ${PORT}`)
)
this is db.js
const mongoose = require('mongoose')
const connectDB = async () => {
try {
const conn = await mongoose.connect(process.env.MONGO_URI, {
useNewUrlParser: true,
useUnifiedTopology: true,
useFindAndModify: false
})
console.log(`MongoDB Connected: ${conn.connection.host}`)
} catch (err) {
//console.log('this is an error')
console.error(err)
process.exit(1)
}
}
module.exports = connectDB
I'm having trouble pinpointing where the bug lies in my code because it seems like my files are in the root folder and MONGO_URI looks like a string. Any help is appreciated.
Can you please try once like this in your env file?
MONGO_URI='mongodb+srv://kpae:XXXX#practice.xujsvaf.mongodb.net/?retryWrites=true&w=majority'
Related
I'm testing my Express routes with Jest and Supertest. While setting up the app, I'm also connecting to MongoDB and adding the MongoClient to app.locals.
I'm getting an error which doesn't happen when I comment out my call to MongoClient.
ReferenceError: You are trying to `import` a file after the Jest environment has been torn down.
at BufferList.Readable (server/node_modules/readable-stream/lib/_stream_readable.js:179:22)
at BufferList.Duplex (server/node_modules/readable-stream/lib/_stream_duplex.js:67:12)
at new BufferList (server/node_modules/bl/bl.js:33:16)
at new MessageStream (server/node_modules/mongodb/lib/cmap/message_stream.js:35:21)
at new Connection (server/node_modules/mongodb/lib/cmap/connection.js:54:28)
/Users/zackchan/Documents/dev/server/node_modules/readable-stream/lib/_stream_readable.js:111
var isDuplex = stream instanceof Duplex;
^
TypeError: Right-hand side of 'instanceof' is not callable
at new ReadableState (/Users/zackchan/Documents/dev/server/node_modules/readable-stream/lib/_stream_readable.js:111:25)
at BufferList.Readable (/Users/zackchan/Documents/dev/server/node_modules/readable-stream/lib/_stream_readable.js:183:25)
at BufferList.Duplex (/Users/zackchan/Documents/dev/server/node_modules/readable-stream/lib/_stream_duplex.js:67:12)
at new BufferList (/Users/zackchan/Documents/dev/server/node_modules/bl/bl.js:33:16)
at new MessageStream (/Users/zackchan/Documents/dev/server/node_modules/mongodb/lib/cmap/message_stream.js:35:21)
at new Connection (/Users/zackchan/Documents/dev/server/node_modules/mongodb/lib/cmap/connection.js:54:28)
at /Users/zackchan/Documents/dev/server/node_modules/mongodb/lib/core/connection/connect.js:36:29
at callback (/Users/zackchan/Documents/dev/server/node_modules/mongodb/lib/core/connection/connect.js:280:5)
at TLSSocket.connectHandler (/Users/zackchan/Documents/dev/server/node_modules/mongodb/lib/core/connection/connect.js:325:5)
at Object.onceWrapper (events.js:421:28)
When I comment out my MongoClient call, I get this Jest warning:
Jest did not exit one second after the test run has completed.
This usually means that there are asynchronous operations that weren't stopped in your tests. Consider running Jest with `--detectOpenHandles` to troubleshoot this issue.
Here's my test script and app module
app.js
const https = require('https');
const fs = require('fs');
const path = require('path');
const dotenv = require('dotenv');
const express = require('express');
const rateLimiter = require('express-rate-limit');
const { MongoClient } = require('mongodb');
const app = express();
const port = process.env.PORT || 443;
const limit = rateLimiter({ window: 15 * 60 * 1000, max: 100 });
var httpsOptions;
if(process.env.NODE_ENV === 'development'){
const rootCA = require('ssl-root-cas').create().addFile(path.join(__dirname, './cert/CA.pem'));
https.globalAgent.options.ca = rootCA;
httpsOptions = {
key: fs.readFileSync(path.join(__dirname, './cert/localhost.key')),
cert: fs.readFileSync(path.join(__dirname, './cert/localhost.crt'))
};
}
MongoClient.connect(process.env.MONGODB_URI, { useNewUrlParser: true, useUnifiedTopology: true }, (err, mongoClient) => {
if(err) throw err;
app.locals.mongoClient = mongoClient;
});
app.use(limit);
app.use(express.json());
app.get('/', (req, res) => {
res.json({path: '/'});
});
const server = https.createServer(httpsOptions, app).listen(port);
module.exports = app;
test.js
const dotenv = require('dotenv');
const path = require('path');
process.env = dotenv.config({path: path.resolve(__dirname, '.env')}).parsed;
const request = require('supertest');
const app = require('../app');
describe('GET /', () => {
it('responds with path of /', (done) => {
// app.locals is empty here
request(app).get('/').expect(JSON.stringify({path: '/'}), done);
});
});
I've tried closing the connection to MongoDB after the test case using app.locals.mongoClient.close() but mongoClient is undefined here. I've also tried wrapping the MongoClient.connect() call in an async function then calling it but that doesn't help either.
Anyone have thoughts on what I should try?
I fixed this by:
Following instructions from Jest docs. You can still access the MongoDB connection through req.app.locals if you assign it to app.locals in the test.js file.
Wrapped my MongoClient.connect() call in app.js:
if(process.env.NODE_ENV === 'production'){
MongoClient.connect(...)
}
I am trying to connect to MongoAtlas, however I keep getting
Error: invalid schema, expected mongodb
It seems to be that I can connect, but it cannot get my db from MongoAtlas. My try catch error returns me (node:5964) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'collection' of undefined
.env
PORT = 9055
MONGO_URI =mongodb+srv://<my-db-username>:<my-password>#cluster0.vossd.mongodb.net/<db-name>?
retryWrites=true&w=majority
server.js
require('dotenv').config();
const port = Number.parseInt(process.env.PORT, 10);
const mongoUri = process.env.MONGO_URI;
const {MongoClient} = require('mongodb');
const express = require('express');
const Application = require('./application');
const application = Application();
const Health = require('./health');
const Product = require('./product');
const Cart = require('./cart');
const Order = require('./order');
async function main() {
let db;
try {
db = await MongoClient.connect(mongoUri);
console.log(db)
} catch (err) {
console.log(err);
}
application.use('/health', Health());
application.use('/product', Product(db));
application.use('/cart', Cart(db));
application.use('/order', Order(db));
const server = application.listen(port, () => {
const host = server.address().address;
const port = server.address().port;
console.log(`Shopping website server up and running, listening at http://${host}:${port}`);
});
}
main();
Everything works fine when I'm connected to my local db, so I'm unsure as to what I'm doing incorrectly. Any advice is much appreciated. Thank you!
This cannot read property 'collection' of undefined might be misleading as you have caught the error happening on connection. Hence db is null so if you access collection it will give this error. Below is the sample code from Mongo Atlas.
const MongoClient = require('mongodb').MongoClient;
const uri = "mongodb+srv://<username>:<password>#test.w7hgn.mongodb.net/<dbname>?retryWrites=true&w=majority";
const client = new MongoClient(uri, { useNewUrlParser: true }); // <-- note the option
client.connect(err => {
const collection = client.db("test").collection("devices");
// perform actions on the collection object
client.close();
});
I'm am trying to connect my react app with a node api to my cosmos db. I'm able to get the server running but when I send a post or get request I don't get a response. I've updated the firewall to allow my ip and I've read just about every article I can find on connecting to cosmos, but none of the resources have helped.
Here is the connection code
const mongoose = require('mongoose');
const env = require('./env/environment');
mongoose.set('useNewUrlParser', true);
mongoose.set('useUnifiedTopology', true);
mongoose.Promise = global.Promise;
const mongoUri = `mongodb://${env.dbName}:${env.key}#${env.dbName}.mongo.cosmos.azure.com:${env.cosmosPort}/?ssl=true&replicaSet=globaldb&retrywrites=false&maxIdleTimeMS=120000&appName=#${env.dbName}#`;
function connect() {
return mongoose.connect(mongoUri, { auth: { user: env.dbName, password: env.key }});
}
module.exports = {
connect,
mongoose
};
and then the env file looks like this
const cosmosPort = 1234; // replace with your port
const dbName = 'your-cosmos-db-name-goes-here';
const key = 'your-key-goes-here';
module.exports = {
cosmosPort,
dbName,
key
};
The env file has the actual information this is just an example.
Are you sure .env file can use const to define params? I'm not sure that. But I follow the offical document, I can connnect cosmosdb successfully.
It is recommended to refer to my screenshot, create a .env file, and replace your parameters to try.
var mongoose = require('mongoose');
var env = require('dotenv').config();
mongoose.connect("mongodb://"+process.env.COSMOSDB_HOST+":"+process.env.COSMOSDB_PORT+"/"+process.env.COSMOSDB_DBNAME+"?ssl=true&replicaSet=globaldb", {
auth: {
user: process.env.COSMODDB_USER,
password: process.env.COSMOSDB_PASSWORD
},
useNewUrlParser: true,
useUnifiedTopology: true,
retryWrites: false
})
.then(() => console.log('Connection to CosmosDB successful'))
.catch((err) => console.error(err));
I think your mongoUri need to be in this format mongodb://${env.dbName}:${env.key}#${env.dbName}.mongo.cosmos.azure.com:${env.cosmosPort}/?ssl=true&replicaSet=globaldb&retrywrites=false&maxIdleTimeMS=120000&appName=#${env.dbName}#
Took some digging for me, and the documentation isn't great.
Today I try open my server, but it doesn't start
Full code - https://github.com/meln1337/error-proxy
app.js
const express = require('express')
const config = require('config')
const mongoose = require('mongoose')
const app = express()
app.use(express.json({extended: true}))
app.use('/api/auth', require('./routes/auth.routes'))
const PORT = config.get('port') || 5000
async function start () {
try {
await mongoose.connect('mongodb+srv://borys:1q2w3e4r5t6y7u8i#cluster0-puuhz.mongodb.net/app', {
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true
})
app.listen(PORT, () => {
console.log(`App has been started on port ${PORT}...`)
})
} catch (e) {
console.log('Server error', e.message)
process.exit(1)
}
}
start()
config/default.json
{
"port": 5000
}
Does the server not start due to mongodb?
If not then why does the server not start?
I was able to run it, locally, with a few changes to "remove" missing files (i.e., changing your mongodb uri to a localhost thingy).
Have you checked your console? When I run it, I get (assuming I have config), TypeError: config.get is not a function. So unless I'm missing something, that's your first issue.
The second is that, for me, obviously the Mongodb instance won't work. I assume that's not true for you - you don't get error querySrv ENODATA - but that's worth checking too.
Finally, if your question is still about mongodb, why not remove that? Just comment out the await... bit, and see if the server starts?
I am unable to connect to cloud mongodb with the following code. Can anyone please tell me whats wrong with this code?
name: 'MongoNetworkError',
errorLabels: [ 'TransientTransactionError' ],
[Symbol(mongoErrorContextSymbol)]: {} }
const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const app = express();
//body parser middleware
app.use(bodyParser.json());
//db config
const db = require('./config/keys').mongoURI;
//Connect to mongo
mongoose
.connect(db, { useNewUrlParser: true })
.then(() => console.log("MongoDB connected"))
.catch(err => console.log(err));
const port = process.env.PORT || 5000;
app.listen(port, () => console.log('server started on port ${port}'));
There are multiple steps you should follow to be able to connect Mongo DB so first make sure that you created an account plus connecting to a cluster, while creating it you'll be provided with enough info to create a cluster take your time and read.
after doing that the code is very simple:
const mongoose = require("mongoose");
mongoose.connect(
"mongodb+srv://[ACCOUNT NAME]:[PASSWORD]#cluster0-sxlgp.gcp.mongodb.net/test?retryWrites=true&w=majority", { useNewUrlParser: true }
);
replace ACCOUNTNAME and PASSWORD with info you provided when you created your MongoDB account
This can be found in their documentation try taking your time reading the documentation.
I believe your code looks good the error you are getting TransientTransactionError is temporary please use events to handle your connection result
mongoose
.connect(db, { useNewUrlParser: true })
mongooose.connection.once('open', () => {
console.log('db connection success');
});
mongooose.connection.on('err', (err) => {
console.log('db connection failed');
});