Data not shown after connecting to MongoDB using mongoose in node js - javascript

I have a database on mongodb named 'abode' and I am trying to make an API where I can use this data to be displayed on a web app. The file structure of the web app is like this.
app.js
const http = require('http'); //Core Module
const fs = require('fs');
const express = require('express');
const bodyParser = require('body-parser');
const path = require('path'); //Core Module
const mongoose = require('mongoose');
const app = express();
const port = 3001;
Bhk = require('./models/bhk');
//Connect to mongoose
mongoose.connect('mongodb://localhost/abode');
const db = mongoose.connection;
app.get('/api/bhk', (req, res)=>{
Bhk.getBHK(function(err, bhk){
if(err){throw err;}
res.json(bhk);
});
});
bhk.js
const mongoose = require('mongoose');
//BHK schema
const bhkSchema = mongoose.Schema({
Name:{
type: String,
required: true
},
create_date:{
type: Date,
default: Date.now
}
});
const bhk = module.exports = mongoose.model('BHK', bhkSchema);
// Get BHK
module.exports.getBHK = function(callback, limit){
bhk.find(callback).limit(limit);
}
When I run the app it shows an empty array on my webpage. Like this
The server starts successfully and there are no errors shown in my console as well. In the collections of my database I have a collection named - BHK. It consists of two records
{ "_id" : ObjectId("5a6d60827fad61a75bbcb5e9"), "Name" : "2BHK" }
{ "_id" : ObjectId("5a6d60b77fad61a75bbcb5ea"), "Name" : "3BHK" }
However no of these records are shown. I tried searching for various solutions of using a mongo db client, however I could not yet get the required result. I do not know where am I going wrong.

After a lot of surfing through the net and trial and error, I realized MongoDB has a convention for naming collections and databases.
The collection that I had named was 'BHK', which according to its guidelines
and conventions was wrong.
The collection name has to be in lower case and plural which in my case I had to rename the collection to:
bhks

Related

TypeError: Cannot read property 'execute' of undefined . node.js how to export oracle db connection

Hi I am new to node and oracle.I have created a app and made a successfull connection to db.
I need to use connection object across the application how can i do that?
Below is my index.js file
const express = require("express");
const app = express();
const authRoute = require("./routes/auth");
app.use(express.json());
app.use("/api",authRoute) ;
app.listen(3000,function(){
console.log("Node Server : Running on port 3000...");
})
database connection file => connect.js
const oracledb = require('oracledb');
const dotenv = require('dotenv');
dotenv.config();
const connection = oracledb.getConnection(
{
user : process.env.USER,
password : process.env.PASS,
connectString : process.env.ConnectString
},
function(err, connection)
{
if (err) {
console.error(err.message);
return;
}
console.log('Connection was successful!');
connection.close(function(err){
if (err) {
console.error(err.message);
return;
}
});
});
module.exports = connection;
I want to use this db connection in my auth.js file
const router = require('express').Router();
const db = require('../database/connect');
router.post("/authenticate",function(req,res){
//console.log(req);
const user = req.body.username;
const username = {"name" : user};
const pass = req.body.key;
const password = {"pass" : pass};
//const result = db.execute('select * from usertable');// this doesn't work
//console.log(result.rows);
res.send('success');
});
module.exports = router;
when i run const result = db.execute('select * from usertable'); I get the error below.
TypeError: Cannot read property 'execute' of undefined
What am i doing wrong.Can anyone please help.Thanks in advance
I had faced this problem. You must install Oracle install client v 19 in your machine. You have to go to web install oracle instant client base on your machine.
(Update: there is a multi-part series with code showing what you want at https://github.com/oracle/oracle-db-examples/tree/main/javascript/rest-api)
Use a connection pool that is opened at app start. Then the pool cache can be used to get the pool (and then connections) in other modules.
For a web app like yours you definitely want to use a connection pool for performance.
There's a big section on connection pooling in the documentation. E.g see Connection Pool Cache which says:
When pools are created, they can be given a named alias. The alias can
later be used to retrieve the related pool object for use. This
facilitates sharing pools across modules and simplifies getting
connections.
The examples are worth reviewing.

Express.js: create additional mongodb DB in controller

I'm new to MongoDB.
When I create my node.js server I use only one DB connection (on start I connect to it).
But imagine: I have one database with some generic tables, and more databases - each for a custom client.
How can I create those DB at runtime?
start.js:
const mongoose = require("mongoose");
// import environmental variables from variables.env file
require("dotenv").config({ path: "variables.env" });
mongoose.connect(process.env.DATABASE);
mongoose.Promise = global.Promise;
mongoose.connection.on("error", err => {
console.error(`🚫 → ${err.message}`);
});
require("./models/MaintenanceType");
require("./models/Maintenance");
const app = require("./app");
app.set("port", process.env.PORT || 7777);
const server = app.listen(app.get("port"), () => {
console.log('started');
});
variables.env (example):
NODE_ENV=development
DATABASE=mongodb://db:qwe123#sometest.server.com:412345/webtest
PORT=1234
SECRET=webtest
KEY=webtestcom
and controller:
const mongoose = require("mongoose");
const Maintenance = mongoose.model("Maintenance");
exports.createMaintenance = async (req, res) => {
const maintenance = await new Maintenance(req.body).save();
// ALSO create a db and table if not exists for this client and use it somehow
res.json(maintenance);
};
is it possible to do?
You can create new connection
mongoose.connect('URI_FOR_ANOTHER_DATABASE')
But it's bad idea to create new connections, so the driver has a feature to use existing connections to query another database, for this purpose you can check useDb() method as shown here

How to take clientside Javascript arrays and POST through a Node.js API into a MongoDB database?

I have a single webpage that initially has two form inputs, one for a list of names and another for the title of a game. I've written some javascript/jquery that takes the X names and creates X more form inputs meant for each person's specific score. The javascript then creates the following variables upon the clicking of the names/scores form's submit button:
gameTitle = Monopoly
users = [Bob, Bill, Jim, Janet]
scores = [100, 110, 90, 80]
positions = [2, 1, 3, 4]
I then have a MongoDB schema set up as such:
const SessionSchema = new mongoose.Schema({
gameTitle: String,
users: [],
scores: [],
positions: []
});
And a Node.js handler as such:
const express = require('express');
const router = express.Router();
const bodyParser = require('body-parser');
const timestamps = require('mongoose-timestamp');
router.use(bodyParser.urlencoded({ extended: true }));
router.use(bodyParser.json());
const Session = require('./Session');
//Post a session to the database
router.post('/', function(req, res) {
Session.create({
gameTitle : req.body.gameTitle,
users : req.body.user,
scores : req.body.score,
positions : req.body.position
},
function (err, session) {
if (err) return res.status(500).send("There was a problem adding the information to the database");
res.status(200).send(session);
});
});
Using Postman I can see that posting works when I use this format:
Postman POST
Postman GET
How do I take the created javascript variables and, also upon the clicking of the names/scores form's submit button, POST them through the API and into the MongoDB database?
Apologies if I have missed any important information/code - I haven't fully wrapped my head around how the backend stuff works.
You need to register your Schema:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const SessionSchema = new mongoose.Schema({
gameTitle: String,
users: [],
scores: [],
positions: []
});
module.exports = mongoose.model('session', SessionSchema);
And here you need to use the mongo schema model, like this:
const express = require('express');
const router = express.Router();
const bodyParser = require('body-parser');
const timestamps = require('mongoose-timestamp');
router.use(bodyParser.urlencoded({ extended: true }));
router.use(bodyParser.json());
const SessionSchema = require('./Session'); // register the mongo model
const mongoose = require('mongoose');
const Session = mongoose.model('session');
//Post a session to the database
router.post('/', function(req, res) {
const new_session = {
gameTitle : req.body.gameTitle,
users : req.body.user,
scores : req.body.score,
positions : req.body.position
};
new_session.save((err, saved_session) => {
if(err) {
res.json(err);
} else {
res.json(saved_session);
}
});
});
Sounds like you have the backend working. What you're missing is the API request. Since your website is not under the same host:port than your API server, when doing it from the browser you'll face CORS issues. Let's get to that later:
First, you'll be making an API call. You can use axios or fetch. Let's go with fetch here:
fetch(url, {
body: JSON.stringify(yourJavascriptVariablesAsAnObject),
headers: {
'Content-Type': 'application/json'
},
method: 'POST',
})
.then(response => {
// here you can check for status if you want.
// ...
return response.json(); // assuming server returns JSON.
})
.then(responseBody => {
// Do something with the server's response body
});
Now for the CORS problem, if your client app is from create-react-app or at least you're using webpack-dev-server, you can proxy request really easy.
If you're not, then you need to allow CORS on your nodeJS server. The simplest way is to use a library.
PS: CORS basically means you can't do requests from a browser to a service living in a different `url:port:, unless that service explicitly says it's ok.
A third option would be putting both UI and server project behind a Web server like Nginx and proxy the requests, but that sounds too complex for what you need.

Moongose, expressjs and node-webkit

I'm building an app using node-webkit, based on expressjs and mongoose. I'm new to basically all of this.
I've got a mongoDb hosted online and i'm try to use it in my app, but i'm missing something
I created in model folder db.js, where i connect with the db
var mongoose = require('mongoose');
mongoose.connect('mongodb://user:password#ds012345.mlab.com:port/mydb') //this isn't the real link
then my model, clients.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var clientSchema = new Schema ({
name: String,
//other fields
});
var client = mongoose.model('client', clientSchema);
module.exports = client;
Then, in my app.js
var db = require('./model/db')
I'm also using routes, so in my index.js i got
var client = require('../model/clients')
But i cannot use any function (save, find, ecc.), i can just create models.
I think I'm not connecting in the right way all the modules, i was previously using diskdb and i connected to it in my index.js, but i tried in the same way and it doesn't work anyway.
Also, when i build the app, my mongoose connection status is 2.
Here are a few things:
what is ecc? you should connect to something like this: mongoose.connect('mongodb://localhost:27017/test');
27017 is the default port for MongoDB and test is the name of your database. Also make sure you start mongo server with mongod then run mongo console mongo.
Your field should specify type of the data:
var clientSchema = new Schema ({
name: String,
age: Number
});
So you want to save the document into database:
var client = mongoose.model('client', clientSchema);
var data = {
nome: 'something'
};
var user = new client(data);
user.save(function(err) {
if(err) console.log(err);
});
In your route, you can do something like this to query back and send data back to the req:
var express = require('express');
var router = express.Router();
var clientSchema = require('../models/clientSchema');
router.get('/', function(req, res, next) {
UserSchema.find({} , function(err, data) {
if (err) console.log(err);
res.render('index', {
data: data
});
});
});
module.exports = router;
Hope this help!

Mongoose and multiple database in single node.js project

I'm doing a Node.js project that contains sub projects. One sub project will have one Mongodb database and Mongoose will be use for wrapping and querying db. But the problem is
Mongoose doesn't allow to use multiple databases in single mongoose instance as the models are build on one connection.
To use multiple mongoose instances, Node.js doesn't allow multiple module instances as it has caching system in require(). I know disable module caching in Node.js but I think it is not the good solution as it is only need for mongoose.
I've tried to use createConnection() and openSet() in mongoose, but it was not the solution.
I've tried to deep copy the mongoose instance (http://blog.imaginea.com/deep-copy-in-javascript/) to pass new mongoose instances to the sub project, but it throwing RangeError: Maximum call stack size exceeded.
I want to know is there anyways to use multiple database with mongoose or any workaround for this problem? Because I think mongoose is quite easy and fast. Or any other modules as recommendations?
According to the fine manual, createConnection() can be used to connect to multiple databases.
However, you need to create separate models for each connection/database:
var conn = mongoose.createConnection('mongodb://localhost/testA');
var conn2 = mongoose.createConnection('mongodb://localhost/testB');
// stored in 'testA' database
var ModelA = conn.model('Model', new mongoose.Schema({
title : { type : String, default : 'model in testA database' }
}));
// stored in 'testB' database
var ModelB = conn2.model('Model', new mongoose.Schema({
title : { type : String, default : 'model in testB database' }
}));
I'm pretty sure that you can share the schema between them, but you have to check to make sure.
Pretty late but this might help someone. The current answers assumes you are using the same file for your connections and models.
In real life, there is a high chance that you are splitting your models into different files. You can use something like this in your main file:
mongoose.connect('mongodb://localhost/default');
const db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', () => {
console.log('connected');
});
which is just how it is described in the docs. And then in your model files, do something like the following:
import mongoose, { Schema } from 'mongoose';
const userInfoSchema = new Schema({
createdAt: {
type: Date,
required: true,
default: new Date(),
},
// ...other fields
});
const myDB = mongoose.connection.useDb('myDB');
const UserInfo = myDB.model('userInfo', userInfoSchema);
export default UserInfo;
Where myDB is your database name.
One thing you can do is, you might have subfolders for each projects. So, install mongoose in that subfolders and require() mongoose from own folders in each sub applications. Not from the project root or from global. So one sub project, one mongoose installation and one mongoose instance.
-app_root/
--foo_app/
---db_access.js
---foo_db_connect.js
---node_modules/
----mongoose/
--bar_app/
---db_access.js
---bar_db_connect.js
---node_modules/
----mongoose/
In foo_db_connect.js
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/foo_db');
module.exports = exports = mongoose;
In bar_db_connect.js
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/bar_db');
module.exports = exports = mongoose;
In db_access.js files
var mongoose = require("./foo_db_connect.js"); // bar_db_connect.js for bar app
Now, you can access multiple databases with mongoose.
As an alternative approach, Mongoose does export a constructor for a new instance on the default instance. So something like this is possible.
var Mongoose = require('mongoose').Mongoose;
var instance1 = new Mongoose();
instance1.connect('foo');
var instance2 = new Mongoose();
instance2.connect('bar');
This is very useful when working with separate data sources, and also when you want to have a separate database context for each user or request. You will need to be careful, as it is possible to create a LOT of connections when doing this. Make sure to call disconnect() when instances are not needed, and also to limit the pool size created by each instance.
Mongoose and multiple database in single node.js project
use useDb to solve this issue
example
//product databse
const myDB = mongoose.connection.useDb('product');
module.exports = myDB.model("Snack", snackSchema);
//user databse
const myDB = mongoose.connection.useDb('user');
module.exports = myDB.model("User", userSchema);
A bit optimized(for me atleast) solution. write this to a file db.js and require this to wherever required and call it with a function call and you are good to go.
const MongoClient = require('mongodb').MongoClient;
async function getConnections(url,db){
return new Promise((resolve,reject)=>{
MongoClient.connect(url, { useUnifiedTopology: true },function(err, client) {
if(err) { console.error(err)
resolve(false);
}
else{
resolve(client.db(db));
}
})
});
}
module.exports = async function(){
let dbs = [];
dbs['db1'] = await getConnections('mongodb://localhost:27017/','db1');
dbs['db2'] = await getConnections('mongodb://localhost:27017/','db2');
return dbs;
};
I have been using this method and it works great for me until now.
const mongoose = require('mongoose');
function makeNewConnection(uri) {
const db = mongoose.createConnection(uri, {
useNewUrlParser: true,
useUnifiedTopology: true
});
db.on('error', function (error) {
console.log(`MongoDB :: connection ${this.name} ${JSON.stringify(error)}`);
db.close().catch(() => console.log(`MongoDB :: failed to close connection ${this.name}`));
});
db.on('connected', function () {
mongoose.set('debug', function (col, method, query, doc) {
console.log(`MongoDB :: ${this.conn.name} ${col}.${method}(${JSON.stringify(query)},${JSON.stringify(doc)})`);
});
console.log(`MongoDB :: connected ${this.name}`);
});
db.on('disconnected', function () {
console.log(`MongoDB :: disconnected ${this.name}`);
});
return db;
}
// Use
const db1 = makeNewConnection(MONGO_URI_DB1);
const db2 = makeNewConnection(MONGO_URI_DB2);
module.exports = {
db1,
db2
}

Categories