Mongoose connect: different behavior between invoking connect in a middleware - javascript

Why when I separate the mongoose.connect invocation to a different file, the program would create new connections every request? It maxed out my mongo atlas connection usage
//I put the connect in a middleware
//middleware.js
const mongoose = require('mongoose')
function connect(req, res, next) {
mongoose.connect(db_url, {}, function (error) { //handle next })
}
module.exports = connect
//and called it in the app
app.use(mongoMiddleware)
The above would create tons of connection, the case is different when I invoke connect in the main app.js
//app.js
mongoose.connect(db_url, {}, function (error) {})
with the above code, the connection usage is 'stable', it doesn't fill out all the available connection.

Instead of using app.use()
(its not needed to use the connection as a middleware,instead make a connect function and export that)
then just require the mongoose connection file in app.js
const mongooseConnection=require("path to the connect function")
the connection code would be we executed when you run the node app.

Related

How to connect front and back end using replit & mongodb?

I made a simple full stack app for a job application using a mern stack. The application requires the app to be deployed on replit. I was able to run my app from my laptop but I am having issue connecting my back end with my front end api calls.
I have not used replit or other online coding platforms much before, so I am not very sure how to. If I run my front end on replit and my back end from my local laptop files, the api calls are working fine. But If I run start both front and back end on replit, the server will start but no API calls will reach it.
Here is the replit link: https://replit.com/#MayurKumar4/In-replit-how-to-connect-to-mongoosemongo-api-endpoints?v=1
Below is the index page of my express app.
The dbURI is currently linked to a mongodb atlas cluster I have set up and is working with some seed data.
port is set to 4000
import express from 'express'
import mongoose from 'mongoose'
import router from './config/routes.js'
import { port, dbURI } from './config/environment.js'
import cors from 'cors'
const app = express()
const startServer = async () => {
try {
// Attempt mongodb connection
await mongoose.connect(dbURI)
console.log('Mongodb connected')
// --Middleware--
// JSON Parser
app.use(express.json())
app.use(cors())
// Logger
app.use((req, _res, next) => {
console.log(`🚨 Request received: ${req.method} - ${req.url}`)
next()
})
// Routes
app.use('/api', router)
// Catch All
app.use((_req, res) => {
return res.status(404).json({ message: 'Route Not Found' })
})
// If mongodb connects successfully
app.listen(port, () => console.log(`🚀 Server listening on port ${port}`))
} catch (err) {
console.log(err)
}
}
startServer()

Node.JS Web Application Create MongooseDB Connection

I'm trying to create a connection to MongoDB from a Node.JS application but I can't get the connection working. I just get errors saying:
TypeError: mongoose.createConnection is not a function
Same for just mongoose.connection also..
I just have a serivce class and I'm trying to create a connecting inside of it:
const mongoose = require('mongoose');
export class MongoDbService{
constructor(){
db = mongoose.createConnection(url)
.on('error', console.error.bind(console, 'connection error:'))
.once('open', function callback() {
console.log('db connection open');
});
console.log(db);
}
Surely this is possible ???
I'm trying to build a web application that talks to mongodb, nothing fancy at all.. Mongoose v5.1.6 is install also.

How can I load my mongoose db before any routing occurs in my express app?

My index template is loading without any mongoose data. But every
page later looks fine. It has something to do with mongoose loading too late/my routes firing too fast. How can I control this?
https://github.com/MartinMars100/search-1
First of all you should connect to mongoose before requiring express app.
Besides you can create class (if you use es6) for your express app, create init method that would connect your routes. So you can call this method after mongoose connection.
It's pretty straight-forward. Here is the code you use to connect to the database. You are currently setting up express in parallel. Move all of that code to the place where I put the comment "put your express stuff here", and it will happen after mongo gets initialized.
mongoose.connect(process.env.MONGODB_URI || 'mongodb://localhost/search-therapy', { useMongoClient: true }, function(err) {
if(err) {
console.log('Failed connecting to Mongodb');
// var app = express();
} else {
console.log('Successfully connected to Mongo');
// put your express stuff here
}
});

NodeJS Socket.io call from another javascript file

I am working on a node project where I need to use websockets. I got the basic implementation working for socket.io in my project. Here is the code for server.js so far
import app from '../app';
import http from 'http';
import socket from 'socket.io';
var server = http.createServer(app);
server.listen(app.get("port"));
server.on('error', onError);
server.on('listening', onListening);
const io = socket(server);
io.on('connection', (socket) => {
console.log(`connected ${socket.id}`);
socket.on('disconnect', () => {
console.log('disconnected');
});
});
Now if I need to call socket from another javascript file, how do I do that?
Something like this: From a.js I would like to call emit message from download function. The problem is that I don't have reference to socket object in a.js. It was defined in my server.js file. Any suggestions?
export const download = () => {
//after file is downloaded, emit message using socket.io to user
}
you need to inject the object into a function that you're calling. is a Dependency Injection principle in programming.
you can
a.js
export const download = (io) => { // io is the reference
//do something with io like io.emit
}
then in your server you need to import the download function then pass the io in your code.
import {download} from "<src/file/of/a.ts>"
// somewhere in the code in server.js
download(io);
for Dependency Injection Principle reference https://en.wikipedia.org/wiki/Dependency_injection
and What is dependency injection?

Socket.io emit from Express controllers

I'm quite new to Node.js / Express, and I'm using it as a backend for an AngularJS app. I've looked all over StackOverflow for some help on my problem, but I can't seem to figure out how to port the suggestions to my code.
My application works as follows:
A long running Scala process periodically sends my Node.js application log messages. It does this by posting to an HTTP API
When the post is received, my application writes the log message to MongoDB
The log messages are then sent in real time to the Angular client.
I am having a problem with Node's modules, as I can't figure out how to refer to the socket instance in the Express controller.
As you can see, in server.js, socket.io is instantiated there. However, I would like the controller itself, logs.js, to be able to emit using the socket.io instance.
How can I refer to io in the controller? I'm not sure how to pass the io instance to the controller so I can emit messages?
Here is some of the Node code:
server.js
var app = express(),
server = require('http').createServer(app),
io = require('socket.io').listen(server);
require('./lib/config/express')(app);
require('./lib/routes')(app);
server.listen(config.port, config.ip, function() {
console.log('Express server listening on %s:%d, in %s mode', config.ip, config.port, app.get('env'));
});
io.set('log level', 1); // reduce logging
io.sockets.on('connection', function(socket) {
console.log('socket connected');
socket.emit('message', {
message: 'You are connected to the backend through the socket!'
});
});
exports = module.exports = app;
routes.js
var logs = require('./controllers/logs'),
middleware = require('./middleware');
module.exports = function(app) {
app.route('/logs')
.post(logs.create);
}
logs.js
exports.create = function(req, res) {
// write body of api request to mongodb (this is fine)
// emit log message to angular with socket.io (how do i refer to the io instance in server.js)
};
You can use a pattern based on standard JS closures. The main export in logs.js will not be the controller function itself, but a factory function that will accept all needed dependencies, and create the controller:
exports.create = function(socket) {
return function(req, res) {
// write body of api request to mongodb
socket.emit();
}
}
Then, when you want to use it:
app.route('/logs').post(logs.create(socket));
Since you set up your routes in a separate package, you have to use the same pattern in routes.js - routes should receive the socket to use as a parameter.
This pattern works well if you want to handle those things with DI later, or test your controllers with mock "sockets".

Categories