I am having trouble connecting my app to Mongo Atlas - javascript

I am following the documentation and based off what I read I am doing it right. I am connecting to my Mongo Atlas server. The server connects and I am able to connect to the DB and the Collection. Yet the DB and the Collection are not being passed to the db object.
I have tried console logging the values and refactored my logic and yet still no solution.
// MongoDB Connection Setup
let db = {};
let MongoClient = require("mongodb").MongoClient;
let uri = process.env.MONGODB_CONNECT_URL;
let client = new MongoClient(uri, { useNewUrlParser: true });
client.connect(err => {
assert.strictEqual(null, err);
console.log('Connected Successfully to MongoDB!');
db.client = client.db("cosmosdb");
db.collection = client.db('cosmosdb').collection('cosmos');
console.log("Database Values: ", db) // This actually returns values
return db;
});
console.log('Database: ', db); // Not returning values
app.set('port', process.env.PORT || 3000);
let server = app.listen(app.get('port'), () => {
console.log(`Express server listening on port: `, server.address().port)
});
server.db = db;
When I console.log db I am expecting to see
Database: {
client: // values
collection: // values
}
yet this is what I am getting back
Database: {}

EDITED
Is your uri assigned like below? (mongodb+srv)
let uri = `mongodb+srv://${dbUser}:${dbPwd}#${dbHost}/test?retryWrites=true`;
let client = new MongoClient(uri, { useNewUrlParser: true });

There is a parameter you are missing on the connect() call, you have "err", but it should be (err, client). So for me it looks as follows:
var db = {};
var MongoClient = require('mongodb').MongoClient;
//Use connect method to connect to the Server
MongoClient.connect(process.env.MONGODB_CONNECT_URL, { useNewUrlParser: true }, function (err, client) {
assert.equal(null, err);
db.client = client;
db.collection = client.db('newswatcherdb').collection('newswatcher');
console.log("Connected to MongoDB server");
});

Related

How to switch between Mongo databases using Mongoose?

What I want to do is to use different databases for different users, for example I have 3 users that would connect to:
www.user1.myfrontend.com
www.user2.myfrontend.com
www.user3.myfrontend.com
Let's suppose that each user want to display the list of products he has, a GET request would be sent to the backend and from there I will connect to the database of the user:
mongodb://mongodatabse:secret#server/databaseOfUser1
mongodb://mongodatabse:secret#server/databaseOfUser2
mongodb://mongodatabse:secret#server/databaseOfUser3
What I did so far:
I connect to the database called config at the start of the app:
db.js
const connect = (uri, app, database="config") => {
const db= mongoose
.createConnection(uri,{ useNewUrlParser: true, useUnifiedTopology: true })
db.on('open', () => {
mongoose.connection.useDb("config")
app.emit('dbReady');
return true;
});
db.on('error', (err) => {
console.log(`Couldn't connect to database': ${err.message}`);
return false;
});
};
server.js
db.connect(process.env.MONGODB_URL, app);
app.on('dbReady', function () {
server.listen(PORT, () => {
console.info(`> Frontend is hosted #: ${process.env.BASE_URL}`);
console.info(`> Database is hosted #: ${process.env.mongodb_url}`);
console.info(`> Listening on port ${PORT}`);
});
});
Then whenever I receive a request I check in the config database for the database to use:
app.js:
const AccessConfig = require('./models/schemas/AccessConfigSchema');
const db = require('./models/db');
app.use(async (req, res, next) => {
const subdomain = req.subdomains[req.subdomains.length - 1];
try {
let database = await AccessConfig.findOne({ subdomain: subdomain});
if (!database)
database= await AccessConfig.findOne({ subdomain: "demo"});
console.log(database);
db.useDb(database);
next();
} catch (e) {
console.log(e.message)
return res.status(500).send('Error: ' + e.message);
}
});
So far It seems like the database isn't changing and I'm not even sure that this is the correct implementation or too many connections are open, etc.
I figured out, you can create connections using
//DB_URI_USER1=mongodb://mongodatabse:secret#server/databaseOfUser1
//DB_URI_USER2=mongodb://mongodatabse:secret#server/databaseOfUser2
const user1Connection = mongoose.createConnection(process.env.DB_URI_USER1, {
useNewUrlParser: true,
useUnifiedTopology: true,
})
const user2Connection = mongoose.createConnection(process.env.DB_URI_USER2, {
useNewUrlParser: true,
useUnifiedTopology: true,
})
Then you create the model for each
const User1 = user1Connection.model(...)
const User2 = user2Connection.model(...)
Now on the API you query the desired model.
Working for me :)

Node JS MongoDB collection.find.toArray returns no value

I'm building a website that lets people write sticky notes and print it to them on the screen. I want to store the sticky notes inside a mongoDB with a db called stickyNotes and a collection called stickyNotes which currently has two documents.
I have a variable called stickyNotes which suppose to get the documents from the stickyNotes collection on the db but when I use the collection.find.toArray from the mongodb library to enter the documents to the stickyNotes variable in an asynchronous way, it shows an empty array value.
This is my server.js file:
const express = require("express");
const mongo = require("mongodb").MongoClient;
const app = express();
let stickyNotes = [];
//mongodb get all sticky notes
const mongoUrl = "mongodb://localhost:27017";
mongo.connect(mongoUrl, { useNewUrlParser: true }, async function(
err,
connection
) {
if (err) {
console.error(err);
} else {
console.log("Succesfully connected to the database");
const db = connection.db("stickyNotes");
const stickyNotesCollection = db.collection("stickyNotes");
stickyNotes = await stickyNotesCollection.find({}).toArray();
}
connection.close();
});
console.log(stickyNotes);
app.use(express.static("./src/public"));
app.get("/sticky-notes", (req, res) => {
console.log("Got a request for sticky notes");
res.json(stickyNotes);
});
const port = 3000;
app.listen(port, () => {
console.log(`App is running on port ${port}`);
});
Can try with:
stickyNotesCollection.find({}, (err, result) => {
if (err) throw err;
stickyNotes = result;
});
or find result in array:
collection.find().toArray(function(err, result) {
console.log(result);
});
or iterate:
collection.find().each(function(err, result) {
//once result
});

Connecting Multiple Mongo DBs in a Node.js Project

I am trying to connect multiple MongoDB databases into a single Node.js project. Here is my current structure and issue at hand.
Node Version: v6.12.1
Express.js Version: 4.16.2
Mongoose Version: 4.13.6
Current Structure:
primaryDB.js
var mongoose = require('mongoose');
var configDB = require('./database.js');
//Connect to MongoDB via Mongoose
mongoose.Promise = require('bluebird');
//mongoose.Promise = global.Promise;
mongoose.connect(configDB.url, { useMongoClient: true });
//Check for successful DB connection
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function() {
console.log("Primary DB Successfully Connected..");
});
module.exports = mongoose;
secondaryDB.js
var mongoose = require('mongoose');
mongoose.connect('mongodb://mongodb_address_goes_here:27017/db_name', { useMongoClient: true });
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function() {
console.log("Secondary DB Successfully Connected..");
});
module.exports = mongoose;
Then each DB connection gets imported respectively into their schema files, from which the schema files have module exports.
Issue at hand
When I run my application it starts fine and connects to both DB's successfully however I believe that mongoose is either getting overwritten or something because I might be able to do a findOne() command on primary but secondary fails or vice versa.
Example:
var async = require('async');
var primaryModel = require('../../../models/general/primary');
var SecondaryModel = require('../../../models/general/secondary');
function getInfo() {
async.waterfall([
getPrimaryName,
getSecondaryName
], function (err, info) {
});
};
function getPrimaryName(callback){
Primary.findOne({}, function (err, primaryInfo){
if (err) {
console.log("Error" + err);
}
console.log('Primary info is : ' + primaryInfo);
callback(null,primaryInfo);
});
}
function getSecondaryName(primaryInfo, callback) {
console.log(primaryInfo); //Make sure its being passed
Secondary.findOne({}, function (err, secondaryInfo) {
if (err) {
console.log("Error" + err);
}
console.log('Secondary Info is : ' + secondaryInfo);
callback(null, secondaryInfo);
});
}
The problem with above is I might get data back from the call to Primary but not Secondary. Which again I believe is from something being overridden .
Any help appreciated. Sorry about the verbosity.
use mongoose.createConnection to create your connections
so
const conn1 = mongoose.createConnection('first server options')
const conn2 = mongoose.createConnection('second server options')
read more here
http://mongoosejs.com/docs/connections.html#multiple_connections

Too many mysql connections / optimizing mysql query

After using my node applications for a couple of time I always get problems with too many MySQL queries. Currently I am using a MySQL Connection Pool which already increased the stability but isn't a final solution.
Is there a better way to connect to the MySQL database and close the connection directly after the query?
General "MySQL Connection":
const mysql = require('mysql');
const config = require('config');
const dbConfig = config.get('Azure.dbConfig');
console.log(`used mysql information: ${dbConfig}`);
const con = mysql.createPool(dbConfig
);
con.on('enqueue', () => {
console.log('connection enqued')
});
con.on('connection', function (connection) {
connection.query('SET SESSION auto_increment_increment=1')
});
con.on('release', function (connection) {
console.log('Connection %d released', connection.threadId);
});
module.exports = con;
Example for a MySQL query:
const con = require('../db.js');
const bodyParser = require('body-parser');
module.exports = function (app) {
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
app.get('/dbCompareName', function (req, res) {
const ingredients = [];
con.query('SELECT wm_wine.name, wm_wine.avocandoIngredient, wm_wine.jahrgang, wm_wine.sorte, wm_cart.anzahl, wm_wine.typ from wm_wine INNER JOIN wm_cart on wm_cart.id = wm_wine.id', function (err, result, info) {
if (err) {
console.log('while querying the mysql database, an error occurred');
console.log(err);
if (err.fatal === true) {
con.connect(err => {
if (err) throw err;
logger.info('reconnected to mysql database');
});
};
}
else {
const transfer = result;
};
};

connecting to mysql from ejs file

I am new to node.js and am trying to learn how to connect to mysql database from ejs file. I tried to search for sample code however the code is not working. Can someone please check it out for me. Thank you.
function loaddata() {
var sql = require("mysql");
var con = mysql.createConnection({});
con.connect(function (err) {
if (err) {
console.log('Error connecting to Db');
return;
}
console.log('Connection established');
});
con.query('update students set name="sus" where email="smn14#mail.aub.edu"', function (err, rows) {
if (err) throw err;
console.log('Data received from Db:\n');
console.log(rows);
});
con.end(function (err) {
// The connection is terminated gracefully
// Ensures all previously enqueued queries are still
// before sending a COM_QUIT packet to the MySQL server.
});
}
The create connect is worst.
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost',
user : 'me',
password : 'secret',
database : 'my_db'
});
connection.connect();
connection.query('SELECT 1 + 1 AS solution', function(err, rows,
fields) {
if (err) throw err;
console.log('The solution is: ', rows[0].solution); });
connection.end();
From this example, you can learn the following:
Every method you invoke on a connection is queued and executed in sequence.
Closing the connection is done using end() which makes sure all remaining queries are executed before sending a quit packet to the
mysql server.
Docs
I now understand the process of server/clients. Makes sense, otherwise you would be able to see the database passwords stored in Client.js. :-)
But, there is one way that works for me. The client call a javascript-function and send a message to the server. The server receives this message and starts a database query. Send the result to all clients via socket.io
At the client in the file.ejs
<script type='text/javascript'>
let socket = io.connect();
function getSql(userId) {
socket.emit('start-new-sql-querie',{
userId: userId
});
}
socket.on('new-sql-result', function (data){ // listen for the new sql result
console.log(data.userStatus); // foo something with the new data
})
</script>
<button onclick="getSql(1)">Test sql query</button>
database connection.js at server side
const connection = {
connectionLimit: 10,
host: "localhost",
user: "Abc",
password: "1234",
database: "d001",
multipleStatements: true
};
module.exports = connection;
yourapp.js at server side
const express = require('express');
const port = process.env.PORT || 1234;
const app = express();
const server = require('http').createServer(app);
const mysql = require('mysql2');
const config = require('./routes/connection'); // SQL-Connection
const pool = mysql.createPool(config);
let io = require('socket.io')(server);
io.sockets.on('connection', function(socket) {
socket.on('start-new-sql-querie', function(data) { // listen from the clients
let user_id = data.userId;
sql_test.getConnection((error, connection) => { // Connect to sql database
console.log("user_id: ", user_id)
connection.query(`SELECT * FROM user WHERE id='${user_id}'`, (err, result) => {
socket.emit('new-sql-result',{ // send sql result-status to all clients
userStatus: result.result[0].status
})
})
connection.release();
})
});
})

Categories