I have node.js project which contain mongo database. I use mongoose schema. 3 file in project are: index.js, users.js and db.js. when I want to connect mongodb via mongoose, I can't. Here is my code. when it runs it says
"error is: TypeError: parseFn is not a function."
pls help!!
db.js
const mongoose=require('mongoose');
mongoose.Promise = require('bluebird');
mongoose.connect('mongodb://localhost:27017/myDB', { useNewUrlParser:true}).then(
(res) => {
console.log("Success!!.")
}).catch((e) => {console.log("error is: " + e);});
users.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var userSchema= new Schema({
id:{type : Number, required: true, unique:true},
username : String,
password : String }, {collection: 'userTB'});
var userS= mongoose.model('userTBL', userSchema);
module.exports=userS;
index.js
...
var db=require('./app_server/models/db');
...
I'm not sure but I guess I faced the same kinda error when I was a newbie in MongoDB. If I'm not wrong this error is because you haven't actually started your local MongoDB server yet. You actually have to start the MongoDB server manually to connect to it. The command to start mongo server from the terminal is something like:
mongod --dbpath /data/db
Related
So i built a frontend where you can fill in a movie name, a review and submit it to a database. Now im trying to connect a mysql database i created to the index.js , so that it gets filled with the first entry. Im trying to accomplish it like this:
const express = require('express');
const app = express();
const mysql = require('mysql');
const db = mysql.createPool({
host: "localhost",
user: "root",
password:"password",
database:'CRUDDatabase',
});
app.get('/', (req, res) => {
const sqlInsert = "INSERT INTO Movie_Reviews(movieName, movieReview) VALUES (1,'inception', 'good movie');"
db.query(sqlInsert, (err, result) =>{
res.send("change done");
});
})
app.listen(3001, () => {
console.log("running on port 3001")
})
But somehow the frontend gets the text ive send "Change done" but the database still doesnt show any entries. Any ideas where my mistake may be? Is it a code mistake or does it have to do with me db configuration. In mysql workbench i just created a default connection without changing anything.
EDIT: The Error seems to be the following:
Error: ER_NOT_SUPPORTED_AUTH_MODE: Client does not support authentication protocol requested by server; consider upgrading MySQL client
EDIT:
The following comment here solved my problem:
Execute the following query in MYSQL Workbench ALTER USER 'root'#'localhost' IDENTIFIED WITH mysql_native_password BY 'password'; Where root as your user localhost as your URL and password as your password Then run this query to refresh privileges: flush privileges; Try connecting using node after you do so. If that doesn't work, try it without #'localhost' part.
I think you have an error in your code but you are not showing it as you don't test in err variable, try this code in order to show what error you are getting:
const express = require('express');
const app = express();
const mysql = require('mysql');
const db = mysql.createPool({
host: "localhost",
user: "root",
password:"password",
database:'CRUDDatabase',
});
app.get('/', (req, res) => {
const sqlInsert = "INSERT INTO Movie_Reviews(movieName, movieReview) VALUES (1,'inception', 'good movie');"
db.query(sqlInsert, (err, result) =>{
if(err) {
console.log(err);
res.send(err.toString());
}
res.send("change done");
});
})
app.listen(3001, () => {
console.log("running on port 3001")
})
So as Med Amine Bejaoui pointed out in a comment, the solution is:
Execute the following query in MYSQL Workbench ALTER USER 'root'#'localhost' IDENTIFIED WITH mysql_native_password BY 'password'; Where root as your user localhost as your URL and password as your password Then run this query to refresh privileges: flush privileges; Try connecting using node after you do so. If that doesn't work, try it without #'localhost' part.
I'm trying to simply post to my MongoDB Atlas db via node,express,mongoose and heroku. A Postman POST request, Raw JSON with body:
{
"title": "heroku post",
"description": "post me plsssss"
}
works on localhost with this exact code, but when uploaded via heroku the try/catch block fails at post.save() as the response is the error.
{
"error": "there's an error",
"message": {}
}
But the error is empty and I'm not sure how to debug it. I've put in mongoose.set('debug', true); in app.js and i've modified my package.json: "start": "node app.js DEBUG=mquery", but those have made no extra output that I am seeing. Is there any other way to know why the post.save() is throwing an error, some logs that I am not utilising.. and how can I see those logs? Or if you just know what the issue is?
App.js
//use dotenv to store secret keys
require("dotenv").config();
const express = require('express');
const mongoose = require('mongoose');
const app = express();
const cors = require('cors');
//connect to DB
mongoose.connect("mongodb+srv://grushevskiy:intercom#cluster-rest.4luv0.mongodb.net/cluster-rest?retryWrites=true&w=majority", { useNewUrlParser: true, useUnifiedTopology: true, dbName: "cluster-rest" }, () => {
console.log('connected to DB!')
})
mongoose.set('debug', true);
const db = mongoose.connection;
db.once('open', () => {
console.log('connection opened')
});
//import routes for middleware
const postsRoute = require('./routes/posts');
//midleware routes
app.use('/posts', postsRoute)
//ROUTES
app.get('/', (req,res) => {
res.send('we are on home')
})
//MIDDLEWARES
//cors
app.use(cors());
//decode url special characters
app.use(express.urlencoded({ extended: true }));
//parse json POSTs
app.use(express.json());
//How do we start listening to the server
app.listen( process.env.PORT || 3000);
posts.js
const express = require ('express')
const router = express.Router();
const Post = require('../models/Post')
//SUBMIT A POST
router.post('/', async (req,res) => {
const post = new Post({
title: req.body.title,
description: req.body.description
});
console.log(post)
try {
const savedPost = await post.save();
res.json(savedPost);
console.log(savedPost)
} catch (err) {
res.json({ error: "there's an error", message: err, })
}
})
module.exports = router;
Post.js Model
const mongoose = require('mongoose')
const PostSchema = mongoose.Schema({
title: {
type: String,
required: true
},
description: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
}
})
module.exports = mongoose.model('Post', PostSchema)
When I type heroku logs --tail there are no errors, also initially, the 'connected to DB!' message comes in a bit late.. I'm wondering if maybe this is an issue with async/await? My package.json:
{
"name": "22-npmexpressrestapi",
"version": "1.0.0",
"engines": {
"node": "14.15.3",
"npm": "6.14.9"
},
"description": "",
"main": "index.js",
"scripts": {
"start": "node app.js DEBUG=mquery",
"start:dev": "node app.js"
},
"author": "",
"license": "ISC",
"devDependencies": {
"express": "^4.17.1",
"nodemon": "^2.0.7"
},
"dependencies": {
"dotenv": "^8.2.0",
"express": "4.17.1",
"cors": "^2.8.5",
"mongoose": "^5.11.11"
}
}
After reading your question carefully I have a couple of suggestions that I think you might want to try. First, let me explain myself:
In my experience, when one learns how to build REST APIs with Node.js, using mongoose to communicate with a MongoDB cluster, this is what the sequence of events of their index.js file looks like:
Execute a function that uses environment variables to establish a connection with the database cluster. This function runs only once and fills de mongoose instance that the app is going to use with whatever models that have been designed for it.
Set up the app by requiring the appropriate package, defining whatever middleware it's going to require, and calling to all the routes that have been defined for it.
After the app has incorporated everything it's going to need in order to run properly, app.listen() is invoked, a valid port is provided and... voila! You've got your server running.
When the app and the databsae are simple enough, this works like a charm. I have built several services using these very same steps and brought them to production without noticing any miscommunication between mongoose and the app. But, if you check the App.js code you provided, you'll realize that there is a difference in your case: you only connect to your Mongo cluster after you set up your app, its middleware, and its routes. If any of those depend on the mongoose instance or the models to run, there is a good chance that by the time Heroku's compiler gets to the point where your routes need to connect to your database, it simply hasn't implemented that connection (meaning hasn't run the mongoose.connect() part) jet.
Simple solution
I think that Heroku is simply taking a little bit longer to run your whole code than your local machine. Also, if your local version is connecting to a locally stored MongoDB, there is a good chance things run quite quicker than in a cloud service. Your statement
the 'connected to DB!' message comes in a bit late
gives me hope that this might be the case. If that were so, then I guess that moving
mongoose.connect("mongodb+srv://xxxxx:xxxxx#cluster-rest.4luv0.mongodb.net/cluster-rest?retryWrites=true&w=majority", { useNewUrlParser: true, useUnifiedTopology: true, dbName: "cluster-rest" }, () => {console.log('connected to DB!')});
to the second line of App.js, right after you call Dotenv, would do the trick. Your mongoose instance would go into App already connected with the database and models that App is going to use.
Asynchronous solution
Even if what I previously wrote fixed your problem, I would like to expand the explanation because, in my experience, that version of the solution wouldn't be right either. The way of doing things that I exposed at the beginning of this answer is ok... As long as you keep your MongoDB cluster and your mongoose instance simple. Not very long ago I had to implement a service that involved a much more complex database pattern, with several different databases being used by the same App, and many of its routes depending directly on those databases' models.
When I tried to use the logic I described before with such a problem, involving heavily populated databases and several models contained in the mongoose instance, I realized that it took Node far less building the App, its middleware, and its routes than connecting to mongoose and loading all the models that that very same App required for it to run. Meaning that I got my Server connected to PORT **** message before the database was actually connected. And that caused trouble.
That made me realize that the only way to do things properly was to ensure asynchronicity, forcing App to run only after all the databases and the models were loaded into the mongoose instance, and feeding it that very same instance. This way, I ended up having an index.js that looked like this:
const Dotenv = require("dotenv").config();
const { connectMongoose } = require("./server/db/mongoose");
const wrappedApp = require("./app");
connectMongoose().then((mongoose) => {
const App = wrappedApp(mongoose);
App.listen(process.env.PORT, () => {
console.log(
`Hello, I'm your server and I'm working on port ${process.env.PORT}`
);
});
});
A file with several functions govering the connections to my databases and modeles called mongoose.js. The function that implements all the connections in the right order looks is:
const connectMongoose = async (mongoose = require("mongoose")) => {
try {
// Close any previous connections
await mongoose.disconnect();
// Connect the Main database
console.log(
"--> Loading databases and models from MongoDB. Please don't use our server jet. <--"
);
mongoose = await connectMother(mongoose);
// Connect all the client databases
mongoose = await connectChildren(mongoose);
console.log(
"--> All databases and models loaded correctly. You can work now. <--"
);
return mongoose;
} catch (e) {
console.error(e);
}
};
module.exports = { connectMongoose };
With this, the file app.js returns a function that needs to be fed a mongoose instance and sets up all the Express environment:
module.exports = (Mongoose) => {
const Express = require("express"); //Enrouting
// Other required packages go here
// EXPRESS SETTINGS
const App = Express();
App.set("port", process.env.PORT || 3000); //Use port from cloud server
// All the middleware App needs
App.use(Flash());
// Routing: load your routes
// Return fully formed App
return App;
};
Only using this pattern I made sure that the chain of events made sense:
Connect all the databases and load their models.
Only after the last database has been connected and its last model, loaded, set up the App, its middleware, and your routes.
Use App.listen() to serve the App.
If your database isn't very large, then the first part of the answer might do the trick. But it's always useful to know the whole story.
I am able to reach an empty error message with your code when i add wrong connection string.
console.log in this callback is incorrect:
mongoose.connect("mongodb+srv://xxxxx:xxxxx#cluster-rest.4luv0.mongodb.net/cluster-rest?retryWrites=true&w=majority", { useNewUrlParser: true, useUnifiedTopology: true, dbName: "cluster-rest" }, () => {
console.log('connected to DB!')
})
if you wanna know if you are connected to db use this:
mongoose.connect("mongodb+srv://xxxxx:xxxxx#cluster-rest.4luv0.mongodb.net/cluster-rest?retryWrites=true&w=majority", { useNewUrlParser: true, useUnifiedTopology: true, dbName: "cluster-rest" });
const db = mongoose.connection;
db.once('open', () => {
console.log('connection opened')
});
I noticed you are using dotenv maybe you are not adding variables to your heroku host.
I have a question about the require function of Node.js, imagine we have a module that manages the connection, and many small modules that contain the routes.
An example of connection file: db.js
const mysql = require('mysql');
const connection = mysql.createConnection({
host : '127.0.0.1',
user : 'root',
password : '',
database : 'chat'
});
connection.connect(function(err) {
if (err) throw err;
});
module.exports = connection;
and one of the various files to manage the routes:
const app = express();
const router = express.Router();
const db = require('./db');
router.get('/save',function(req,res){
// some code for db
});
module.exports = router;
Imagine now to have 20 routes with the same require. How will node.js behave? How many times will my connection be created?
How many times will my connection be created?
There will be one connection, because "db.js" runs only once. The things you export get stored (module.exports) and that gets returned by every require("./db"). To verify:
require("./db") === require("./db") // true
I keep getting an error when trying to connect mongoDB. I know there are many questions similar to this one and I have checked all of them and haven't found a solution for my issue.
Here is the exact error:
connection error: { MongoError: connect ECONNREFUSED 127.0.0.1:21017
name: 'MongoError'
message: connect ECONNREFUSED 127.0.0.1:21017
I looked at some other solutions and they say to adjust the mongo.conf file but I can't seem to find the file on my system and I've downloaded MongoDB.
Here is my full code:
var express = require('express');
var router = express.Router();
var mongoose = require('mongoose');
$ = require('cheerio');
/* GET home page. */
mongoose.connect('mongodb://localhost/');
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function() {
console.log('Connected to database');
// we're connected!
});
var pageInfo = {
title: 'JotIT',
owner: 'Emmanuel Obogbaimhe',
message: 'Hi welcome to JotIT. A quick, simple and easy to use note taker.',
date: Date.now(),
age: 22
};
router.get('/', function(req, res, next) {
res.render('index', {
title: pageInfo.title,
author: pageInfo.owner,
message: pageInfo.message,
date: pageInfo.date,
age: pageInfo.age
});
});
module.exports = router;
The reason for getting that kind of error: {MongoError: connect ECONNREFUSED 127.0.0.1:21017}, is that Mongo process is not running on that PORT, or not running at all.
For first check out if mongo process is running:
service mongod status //for Linux machine
For second - check the port of mongo process:
nmap -p- localhost //for Linux machine
For windows, open another terminal and cd into the apps root directory. Then, run $ mongod.exe. I would recommend placing the following into a test.js file:
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/test.js');
var db = mongoose.connection;
db.on("error", function(error){
console.error("Connection error : " + error)
});
db.once('open', function() {
console.log('Connected to database');
db.close(function(){
console.log("db connection closed");
});
});
Go back to the original terminal and run $ node test.js
I had the same error, It looks like and bad closing in preview mongodb session I just did and It worked out fine
sudo service mongod stop
sudo service mongod start
Had the same problem, caused by running out of hard drive memory space. This caused mongod to keep crashing after restarting it.
Simply increasing memory space of the server, and restarting mongod (either manually or via reboot when service restarts automatically) solved the issue.
Try this
var express = require('express');
var router = express.Router();
var mongoose = require('mongoose');
$ = require('cheerio');
/* GET home page. */
mongoose.connect('mongodb://localhost:27017/db-dev');
or try with
mongoose.connect('mongodb://0.0.0.0:27017/db-dev');
change your mongoose connection code to:
mongoose.connect('mongodb://localhost:27017/yourdb');
This error can be solved by replacing localhost in the following code with the address of localhost which is 127.0.0.1.
mongoose.connect('mongodb://localhost/');
Try this -> mongoose.connect('mongodb://127.0.0.1/');
I use nodejs express and mongoose to connect mongodb,I've created a config.js in root folder.I am trying to exports db connect in db.js and trying to import in adminController.js
But when I run the server and refresh the browser ,it log me some errors and not log my log in terminal.
config.js
module.exports = {
cookieScret:'ThreeKingdoms',
db:'threekingdoms',
host:'localhost',
port:27017
}
db.js
var mongoose = require('mongoose'),
config = require('../config'),
connection = mongoose.connection;
module.exports = function(mongoose){
return mongoose.connect('mongodb://'+config.host+'/'+config.db);
}
adminController.js
var express = require('express'),
router = express.Router(),
mongoose = require('mongoose'),
mainInfo = require('../models/admin'),
db = require('../models/db');
router.get('/', function(req, res) {
res.render('admin', { title: 'hey im here!how are you' });
db.on('error',console.error.bind(console, 'connection error:'));
db.once('open', function() {
console.log(db)
});
console.log(db)
});
router.post('/',function(req,res,next){
//console.log(req.body)
var mainInfo = mongoose.model('mainInfo');
})
module.exports = router;
question files is in red box
terminal error
I am new to nodejs,so please help me,Thanks
First, it seems that you don't have kerberos installed. Please run npm install kerberos.
Also, the line
Can't set headers after they're sent
Suggests you're trying to modify/send the response after it was already sent back to the client, and that's the error you're getting.
finally it is work now,but it doesn't matter with 'kerberos' ,it is i use wrong way to export my module.terminal still log me 'kerberos undefined' but web can work,i think maybe some time i will try to figure this question out.thanks for your attention