I'm trying to connect to mlab using node with little success. I use this line to connect to my db
mongoose.connect(mymlabDBurl, { useMongoClient: true });
I have then tried to test that it works by hitting my API end points. I know this works because the first console.log below works. However when I try and save to my database I never hit the next two console.logs. How can I test for why this connection to the db is failing?
exports.add_name = function (req, res) {
const newName = new Name(req.body);
console.log(newName); //this prints
newName.save(function (err, name) {
console.log(name); //this doesnt print
console.log(err); //this also doesnt print
if (err)
res.send(err);
res.json(name);
});
};
Related
MongoClient.connect(this._config.connectionString, {
useNewUrlParser: true,
useUnifiedTopology: true,
}, (err, db) => {
if (err) {
console.log(`error on connect : ${err}`);
return console.dir(err);
}
console.log('We are connected');
this._client = db;
});
This piece helps me connect to mongodb running locally, and works fine when DBserver is up and running. But if i stop db server and then try to execute this...it doesnt call the call back. Is there a way i can get call back in case of DB is down or not reachable?
below code doesnt get call back, in case of future DB errors.
this._client.on('error', args => this.onError(args));
Because of this issue of not getting call backs, in case of any severe errors...my server goes down without showing any error.
I want to test the saveRecords function for the failure and before that, I have to authenticate and connect the MongoDB. This is the code.
before(() => {
sinon.stub(Authentication, 'authenticate').returns(true);
sinon.stub(mongodb, 'connect').resolves("connected");
sinon.stub(models, 'saveRecords').throws(new Error("Error while saving record"));
});
it('Should error out if record is not inserted into the mongodb
collection', () => {
orderWebhook(req, res)
expect(res.result).to.contain("Error while saving record");
});
Here is the code I am testing.
exports.orderWebhook = async (req, res) => {
try {
const isAuthenticated = Authentication.authenticate(req);
if (isAuthenticated) {
await mongodb.connect();
await models.saveRecords(req.body");
res.status(200).send('Saved Successfully!');
} else {
res.status(403).send('Error! Auth failed!');
}
} catch (error) {
res.status(400).send(error.message);
}
}
I am assuming that this code will stub the authenticate then connect MongoDB and then try to insert the record and throw the error. But it is running two times when I debug with the VSCode debugger.
The first time it is returning true for the authenticate function and not resolving the MongoDB connect and return to expect immediately.
The second time it is running all three properly and throwing the expected error.
It is failing when I run the test in the terminal, What could be the issue?
Update: I noticed that the problem is related to the promise. Sinon is resolving the request and I am using await mongodb.connect(); but it is not working as expected, and if I remove await and return value instead of promise then it works.
I am running a quick little nodejs script to find documents in one collection and insert them into another collection but on the same DB. I came up with this guy, but it has no way to close because I think its running open or async?
I have tried placing the db.close() in various places and tried mongoClient.close(). No luck which had me thinking about trying to force a timeout for the async call. Added a connection Time out but it did not have the desired behaviour.
var MongoClient = require('mongodb').MongoClient
, assert = require('assert');
const async = require("async");
// Connection URL
var url = 'mongodb://localhost:27017/sourceDB';
// Use connect method to connect to the Server
MongoClient.connect(url,{connectTimeoutMS: "5"}, (err, db) => {
db.collection('source.collection', function(err, col) {
assert.equal(null, err);
col.find().forEach(function (data) {
console.log(data);
db.collection('destination.collection').insertOne(data, function(err, res) {
assert.equal(null, err);
});
console.log("Moved");
});
});
});
The script does well and picks up the collection and inserts, but the connection remains open.
It is not recommended to explicitly close the connection as shown by this SO thread.
Rather, allow the client library to manage the connection for you.
I’m trying to pass data from my server app.js to my database file so that I can store it into MongoDB atlas.
I can see where the problem is I'm honestly just not sure how to go about fixing it. The problem seems to be two parts.
1.) I'm passing a function into .insertOne and not an object, this is resulting in a promise error. When I try to change things in the userDataFinal function I start running into scope errors and things not being defined. I'm not really sure how to fix this.
2.) my code is trying to create a new document as soon as it starts up because
db.collection('User').insertOne(userDataFinal);
is located in the .connect callback function.
I need this code to run only when a put request has been made on the client side.
relevant server code app.js
const base = require('./base.js');
app.post('/',(req, res)=>{
var userName = req.body;
base.userDataFinal(userName);
res.render('index');
});
Relevant database code base.js
var userDataFinal = function getUserName(user){
console.log(user);
}
module.exports = {userDataFinal};
////////////////////////////////////////////////////////////////////////
// connects to the database
MongoClient.connect(URL, {useNewUrlParser: true}, (error, client)=>{
if(error){
return console.log('Could not connect to the database');
}
// creates a new collection
const db = client.db(database);
// adds a document to the designated collection
db.collection('User').insertOne(userDataFinal);
console.log('Database is connected...')
});
First, you are passing a callback into your MongoClient.connect() function.
This callback is useful when you want to make sure that you are connected.
As you said it, you want your code to run only when the request has been made. You can remove your insertion from the connect, but you can still keep the error handling part as it is always useful to know why there was a db connection error.
Also, you are calling the mongo insertOne method, that expects an object. You are passing it a function.
EDIT: Create a db variable outside all your functions, then assign it from the Mongo connect callback once you have access to the client.
You will be able to use this db later in the routes.
var MongoClient = require('mongodb').MongoClient;
var db; // Will be set once connected
MongoClient.connect(URL, {useNewUrlParser: true}, (error, client)=>{
if(error){
return console.log('Could not connect to the database');
}
db = client.db(database);
console.log('Database is connected...')
});
app.post('/',(req, res)=>{
var userName = req.body.username;
db.collection('User').insertOne({ username: userName });
res.render('index');
});
Please note that you are probably passing the userName through the body, in this case you need to retrieve it that way: req.body.username (if you named the related body parameter username).
I'm using node js, express and postgresql as backend.
This is the approach I used to make a rest API:
exports.schema = function (inputs, res) {
var query = knex('schema')
.orderBy('sch_title', 'asc')
.select();
query.exec(function (err, schemas) {
if(err){
var response = {
message: 'Something went wrong when trying to fetch schemas',
thrownErr: err
};
console.error(response);
res.send(500, response);
}
if(schemas.length === 0){
var message = 'No schemas was found';
console.error(message);
res.send(400, message);
return;
}
res.send(200, schemas);
});
};
It works but after a while postgres logs an error and it's no longer working:
sorry, too man clients already
Do I need a close each request somehow? Could not find any about this in the express docs. What can be wrong?
This error only occurs on production server. Not on developing machine.
Update
The app only brakes in one 'module'. The rest of the app works fine. So it's only some queries that gives the error.
Just keep one connection open for your whole app. The docs shows an example how to do this.
This code goes in your app.js...
var Knex = require('knex');
Knex.knex = Knex.initialize({
client: 'pg',
connection: {
// your connection config
}
});
And when you want to query in your controllers/middlewares...
var knex = require('knex').knex;
exports.schema = function (req, res) {
var query = knex('schema')
.orderBy('sch_title', 'asc')
.select();
// more code...
};
If you place Knex.initialize inside an app.use or app.VERB, it gets called repeatedly for each request thus you'll end up connecting to PG multiple times.
For most cases, you don't need to do an open+query+close for every HTTP request.