How to create dynamic database in mongodb? - node.js

I'm learning MERN stack development, when I tried to connect the database through .env file, everything was working fine. Here is how my database string looks like:
MYDATABASE_String="mongodb+srv://avnish:avnish#cluster0.ojaf1.mongodb.net/registeredUsers?retryWrites=true&w=majority"
It is working fine when I'm trying to register users, they go under registeredUsers. But now, I'm also implementing blog portion, so when I publish a new blog, it goes under registeredUsers.
Now I want to know how to create a new database dynamically so that it goes to blogContent database and not in registeredUsers database.
Here is how my server.js looks like:
const express = require('express');
const mongoose = require('mongoose')
const app = express();
const dotenv = require('dotenv')
const routesURLs = require('./routes/routes')
const registerRouter = require('./routes/register')
const loginRouter = require('./routes/login')
const blogRouter = require('./routes/blog')
const cors = require('cors')
dotenv.config()
mongoose.connect(process.env.DATABASE_ACCESS,{
useNewUrlParser: true,
useUnifiedTopology: true,
useFindAndModify: false,
useCreateIndex:true
},()=>console.log(
'database connected successfully'),
)
app.use(express.json())
app.use(cors())
app.use('/',routesURLs)
app.use('/register',registerRouter)
app.use('/publish',blogRouter)
app.listen(4000, () => {
console.log(`Server started on port`);
});
This is my blog schema:
const mongoose = require('mongoose')
const blogModel = new mongoose.Schema({
title:{
type:String,
required:true,
},
category:{
type:String,
required:true,
},
slug:{
type:String,
required:true,
},
description:{
type:String,
},
content:{
type:String,
required:true
},
featuredImage:{
type:String,
},
publishedAt:{
type:Date,
default:Date.now
}
})
module.exports = mongoose.model('blog',blogModel)
And this is my blog.js
const { response, request } = require('express');
const express = require('express');
const router = require('express').Router();
const blogModel = require('../models/Blog')
router.post('/',async (req,res)=>{
const blogArticle = new blogModel({
title:req.body.title,
description:req.body.description,
category:"haha",
slug:"some-thing-here",
content:req.body.description,
})
blogArticle.save().then(data=>{
res.json({
data:data,
message:"Hurray all done"
})
}).catch(error=>{
res.json({
error:error,
message:"Lol! Nothing works"
})
})
})
module.exports = router;
Note
When I removed registeresUsers from the mydatabase string, every data goes to Test database.

While I don't agree that each type of document should get an entire database I will explain how to handle this case.
mongoose handles connections at the db level, While Mongodb allows a single connection to have multiple databases this is not the case here.
This means you'll have to create another mongoose instance and connect to the other database. This also means you can just do require('mongoose') anymore for the none default connection as this would be a different mongoose instance. I recommend creating a singleton that will serve the connection on demand to deal with this.
I will also add that mongoose is VERY inconvenient for this use case, I recommend you reconsider the actual need for another database.

Related

Mongoose Schema in NodeJS UnhandledPromiseRejectionWarning: TypeError: Item is not a constructor

I'm building a cafe website with NodeJS, Express, and Mongo. I'm attempting to create a new cafe in one of my routes with a get request using a model I created. However, I keep getting an TypeError in my terminal stating that Cafe is not a constructor. I don't understand because I have defined the Schema in a separate file and I've included it in my app.js (routes file). Any feedback about this error is appreciated. I've included a few photos along with the code. Thank you in advance!
const path = require('path')
const mongoose = require('mongoose');
const Cafe = require("./models/cafe");
mongoose.connect('mongodb://localhost:27017/cafe-hopping', {
useNewURLParser: true,
useUnifiedTopology: true
})
const db = mongoose.connection;
db.on("error", console.error.bind(console, "connection error:"));
db.once("open", () => {
console.log("Database connected");
});
const app = express()
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'))
app.get('/createcafe', async(req, res) => {
const cafes = new Cafe ({ name: 'Cueva Matera', description: "A cave like theme cafe"});
await cafes.save();
res.send(cafes)
})
*The following is the Schema (the file name is cafe.js)*
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const CafeSchema = new Schema({
name: String,
price: String,
description: String,
location: String
});
module.export = mongoose.model('Cafe', CafeSchema);
[![app.js file. This is where I am keeping all of my routes][1]][1]
[![cafe.js file. This is where I create a new Schema for the database][2]][2]
[![This is the server error message I'm getting in my terminal every time I send the /createcafe get request][3]][3]
[1]: https://i.stack.imgur.com/mgTYg.png
[2]: https://i.stack.imgur.com/p9Ibx.png
[3]: https://i.stack.imgur.com/hFzzJ.png
The issue appears to be that you should be using
module.exports = mongoose.model('Cafe', CafeSchema);
Instead of module.export
Because of the misnamed property (export vs exports) the schema is not getting exported correctly, and Cafe is not a constructor.

Empty on collection

I have created database and have make one collection with the name staff there, I have put 3 data and it is showing on mongodb compass. But will try to fetch staff I got empty array. I am baby with this mongo db envirnment so I am unknow where did I get mess on my code.
Here, I have two files. one server.js which is main file and another is model file
server.js
const express = require("express");
const app = express();
const mongoose = require("mongoose");
const Staff = require("./staff");
const dbname = "mydbname";
const dbpass = "mypassword";
const dbuser = "meuser";
mongoose.connect(
"mongodb+srv://"+dbuser+":"+dbpass+"#cluster0.ovjvl.mongodb.net/"+dbname+"?retryWrites=true&w=majority",
{ useNewUrlParser: true, useUnifiedTopology: true })
.then(() => console.warn("db connection done"))
.catch((error) => console.warn("DB Not Connect", error));
Staff.find({},(err,data)=>{
if(err) console.warn(err)
console.warn("Data :",data)
})
staff.js
const mongoose = require("mongoose");
let staffSchema = new mongoose.Schema({
_id : mongoose.Schema.Types.ObjectId,
name:String,
designation:String,
gender:String,
salary:mongoose.Schema.Types.Decimal128,
skills:mongoose.Schema.Types.Array})
module.exports = mongoose.model('staff',staffSchema)
While I run my app I got below ouput
db connection done
Data : []
But am expecting some data on array.
Note : For security reason, I have mention dbname,user & password is fake.

MongooseError: Operation `users.findOne()` buffering timed out after 10000ms

This is my connection file
const connectDB = async () =>{
const conn = await new mongoose("mongodb+srv://nikunj:gadia7420#cluster0.94xph.mongodb.net/myFirstDatabase?retryWrites=true&w=majority",
{
usenewurlparser:true,
usecreateindex:true,
usefindmodify:true,
useunifiedtropology:true,
urlencoded:true
})
}
module.exports = connectDB;
this is my models file
const userSchema = new mongoose.Schema({
username:{
type:String,
required:true
},
avatar:{
type:String,
},
email:{
type:String,
required:true
},
password:{
type : String,
required:true
}
});
module.exports = mongoose.model('user',userSchema);
this file will insert or take information from database for registeration
const express = require('express');
const router = express.Router();
const User = require('../models/user');
const bcrypt= require('bcrypt');
router.post('/register',async(req,res,next)=>{
const {username,email,password}=req.body;
try{
let user_exist = await User.findOne({email:email});
if(user_exist){
success="false";
msg="user already exist";
} else {
//importing data to models
let user = new User();
user.username = username;
user.email = email ;
const salt = await bcrypt.genSalt(10);
user.password = await bcrypt.hash(password,salt),
user.avatar = "https://gravatar.com/avatar/?s=200&d=retro"
await user.save();
res.json({
sucess:true,
user:user,
msg:"user registered"
})
}
}
catch(err){
console.log(err);
}
});
module.exports = router;
this is my main file (server.js )
const express = require('express');
const morgan = require('morgan');
const colors = require('colors');
const dotenv = require('dotenv');
const mongoose = require('mongoose');
const connectDB = require('./config/db');
//creating main platform
connectDB;
console.log(mongoose.connection.readyState);
const app = express();
app.use(morgan('dev'));
dotenv.config({
path:'./config/config.env'
})
app.use(express.json({}))
app.use(express.json({
extended:true
}))
//creating server
app.use('/api/todo/auth',require('./routes/user'));
const Port = process.env.port;
app.listen(Port,
console.log(`listening on port :${Port}` .red.underline.bold));
//creating req,res platform
but after running this it shows error while giving post request
MongooseError: Operation `users.findOne()` buffering timed out after 10000ms
at Timeout.<anonymous> (D:\nikunj\Programming\todoapp\node_modules\mongoose\lib\drivers\node-mongodb-native\collection.js:185:20)
at listOnTimeout (node:internal/timers:556:17)
at processTimers (node:internal/timers:499:7)
pls find a solution for this. thanks .sorry if it is a silly or wrong question because I am new to this nodejs
Connect to your database 1st and after that start your server.
You're trying to query the database without connecting to your database.
https://mongoosejs.com/docs/connections.html#buffering
Mongoose lets you start using your models immediately, without waiting for mongoose to establish a connection to MongoDB.
That's because mongoose buffers model function calls internally. This buffering is convenient, but also a common source of confusion. Mongoose will not throw any errors by default if you use a model without connecting.
connectDB()
.then(() -> {
app.listen(Port, console.log(`listening on port :${Port}` .red.underline.bold));
}).catch((e) => {
console.log(e);
})
You're not calling the function connectDB
Turn on your Mongo Server and connect to your database before you attempt to write to it.
In my case I am using a monorepo, one package initiates the server and another contains the mongoose models.
One of the packages had a different mongoose version on it's package.json's dependencies.
The problem was fixed after making sure both packages had the same version of mongoose and then running yarn at the root of the monorepo to relink dependencies properly.
For anyone wondering, I'm able to use mongoose on two different packages in a monorepo since mongoose is basically a singleton class, meaning that it will usually try to use a pre-existing instance of mongoose wherever it is mentioned without initialization.
Having two versions of mongoose breaks this singleton functionality since (as far as Node is concerned) the instance on the server was created using a different mongoose package than the one on my models package.
TL;DR Make sure any packages in your monorepo depending on mongoose have the same version of mongoose in their respective package.json files.
This question has already been answered, however when I encountered with the same problem, the cause was very different. For some reason I put Mongodb connection URI inside quotes in config vars. Never do that. When I removed the quotes, everything worked just fine.
I faced this problem at mongoose v "^6.3.4" and when I removed my IP from network access on sidebar on mongodb and added it again it worked
I faced this problem at mongoose v "^6.3.4" and when I removed my IP
from network access on sidebar on mongodb and added it again it worked
This worked for me too. I removed my ip and selected "ALLOW ACCESS FROM ANYWHERE" option on the network access page and it worked.
(I think it is safe: "Allow access from anywhere" MongoDB Atlas)

Get existing document from MongoDB with Mongoose

I have an existing document on MongoDB atlas that I need to get in its entirety. When I try my current code I get a socket timeout, i.e. it keeps buffering.
There is only one document in my collection.
My theory is that the error is in my Mongoose Schema, but I don't know what to put there since I don't want any "filters", I want everything.
The name of the collection in Atlas is Playstation and the id of the document I want to get is: 5f5e2d281386efc27bb3ce45
const express = require('express')
const router = express.Router()
const Playstation = require('../models/playstation')
//Getting All
router.get('/', async (req, res) => {
try {
const playstations = await Playstation.findById("5f5e2d281386efc27bb3ce45")
res.json(playstations)
} catch (err) {
res.status(500).json({ message: err.message })
}
})
module.exports = router;
My schema & model:
const mongoose = require('mongoose')
const playstationSchema = new mongoose.Schema({
})
module.exports = mongoose.model('Playstation', playstationSchema)
I believe the problem is your mongoose schema. What you want is a schemaless collection, since you dont want to define the schema, and you want everything in the document, you can define the collection as schema-less, with strict:false option in your mongoose schema;
Try this:
const mongoose = require('mongoose')
const playstationSchema = new mongoose.Schema({
},{ strict : false })
module.exports = mongoose.model('Playstation', playstationSchema);
You can read more about this option on Mongoose Documentation

Node.js API express web server MongoDB

I'm writing an Node.js REST API using express web server and mongoDB as DB server.
The project's directory tree is the following :
https://i.stack.imgur.com/LFWGt.png
When I try to access "/new/test" route, I'm getting the error "Cannot GET /new/test". By accessing this path it should create an new entry into the DB based on "firstname" URL parameter.
Routes.js :
'use strict';
module.exports = function(app) {
var americaine = require('../controllers/americaineController');
// Firstname Routes
app.route('/new/:firstname')
.post(americaine.new_firstname);
};
DB entry creation function is located on Controller.js :
'use strict';
var mongoose = require('mongoose'),
Firstname = mongoose.model('Firstname');
exports.new_firstname = function(req, res) {
var new_firstname = Firstname(req.params.firstname);
new_firstname.save(function(err, firstname) {
if (err)
res.send(err);
res.json(firstname);
});
};
Model.js :
'use strict';
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var FirstNameSchema = new Schema({
/*id: {
type: Number,
required: false
},*/
name: {
type: String,
required: true
}
});
module.exports = mongoose.model('Firstname', FirstNameSchema);
Do you guys have any ideas about my issue ? Thanks in advance.
Jérémy
change the method .post() to .get()
since you're actually doing a get request and not a post request.

Resources