I am having trouble connecting my server to MongoDb database using mongoose. The server will start and then crash while trying to connect to mongoDB. the error is getting caught in db.js and then exiting the program. It seems the server will connect to local host then end when it trys to connect to mongoDB.
ERROR!
[nodemon] restarting due to changes...
[nodemon] starting `node server.js`
Server is running on : http://localhost:8000
MongoDB is not connected
[nodemon] app crashed - waiting for file changes before starting...
here Is my db.js I have linked it to my sever.js file
const mongoose = require('mongoose')
const connectDB = async()=>{
try{
await mongoose.connect("mongodb+srv://jj-test:jj#videos.cdstjfw.mongodb.net/?retryWrites=true&w=majority")
console.log("MongoDB is connected!")
}catch(err){
console.log("MongoDB is not connected")
console.error()
process.exit(1)
}
}
module.exports=connectDB
server.js
const express = require("express");
const cors = require("cors");
const dotenv = require('dotenv');
const mongoose = require('mongoose')
const crypto = require('crypto')
const path = require('path')
const GridFsStorage = require('multer-gridfs-storage')
const multer = require('multer')
const Grid = require('gridfs-stream')
const connectDB= require('./services/db')
const PORT = process.env.PORT || 8000;
const app = express();
const init = async ()=>{
app.use(express.json());
app.use(express.urlencoded({ extended: false }))
app.use(cors());
await connectDB()
const conn = mongoose.connection
const gfs = await Grid(conn.db,mongoose.mongo)
gfs.collection('media')
// storage location using muster
const storage = await new GridFsStorage({
db: conn.db,
file: (req, file) => {
return new Promise((resolve, reject) => {
crypto.randomBytes(16, (err, buf) => {
if (err) {
return reject(err);
}
const filename =
buf.toString('hex') + path.extname(file.originalname);
const fileInfo = {
filename,
bucketName: 'media'
};
return resolve(fileInfo);
});
});
}
});
const upload = multer({ storage });
// uploading a file route
app.post('/upload',upload.single('file'),(req,res)=>{
res.json(req.file)
})
// media bucket route
app.get('/files',async(req,res)=>{
try{
const files =await gfs.files.find().toArray()
res.json(files)
}catch(err){
res.status(400).send(err)
}
})
// route for streaming a file
app.get('/read/:filename',async(req,res)=>{
const{filename}= req.params
try{
const readstream = await gfs.createReadStream({filename})
readstream.pipe(res)
}catch(err){
res.status(400).send(err)
}
})
app.delete('/delete/:filename',async(req,res)=>{
const{filename}=req.params
try{
await gfs.files.remove({filename})
res.status(200).end()
}catch(err){
res.status(400).send(err)
}
})
}
init()
app.listen(PORT, () => {
console.log(`Server is running on : http://localhost:${PORT}`);
});
Also worthwhile adding console.log(err) to help give more descriptive error info on the server.js file
You need add database name:
mongoose.connect("mongodb+srv://jj-test:jj#videos.cdstjfw.mongodb.net/DATABASEname?retryWrites=true&w=majority")
Related
I'm following this tutorial and I'm stuck at the end. getting 404's in postman when using POST with this URL http://localhost:5050/api/projects its been 3 days any one know what I'm doing wrong?
server.js
const express = require("express");
const app = express();
const PORT = 5050;
// Connect to the database
require("./src/server/database/connection");
const bodyParser = require("body-parser");
const cors = require("cors");
var corsOptions = {
origin: "http://localhost:5051"
};
app.use(cors(corsOptions));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.json());
// parse requests of content-type - application/x-www-form-urlencoded
app.use(express.urlencoded({ extended: true }));
// simple route
app.get("/", (req, res) => {
res.json({ message: "Code Wire Server." });
});
require("./src/server/routes/routes")(app);
app.listen(PORT, () => {
console.log(`Server is listening at http://localhost:${PORT}`);
});
connection.js
How to connect to the database
const db = require("../model/index.js");
db.mongoose
.connect(db.url, {
useNewUrlParser: true,
useUnifiedTopology: true
})
.then(() => {
console.log("Connected to the database!");
})
.catch(err => {
console.log("Cannot connect to the database!", err);
process.exit();
});
index.js
const dbConfig = require("../config/db.config.js");
const mongoose = require("mongoose");
mongoose.Promise = global.Promise;
const db = {};
db.mongoose = mongoose;
db.url = dbConfig.url;
db.project = require("./projects_db.js")(mongoose);
module.exports = db;
db.config.js
module.exports = {
url: "mongodb://127.0.0.1:27017/code-wire-db"
}
projects_db.js
A database schema for my project I'm working on
module.exports = mongoose => {
var schema = mongoose.Schema({
project_title: String,
description: String,
} );
schema.method("toJSON", function() {
// eslint-disable-next-line no-unused-vars
const { __v, _id, ...object } = this.toObject();
object.id = _id;
return object;
});
const projectsDB = mongoose.model("projectsDB", schema);
return projectsDB;
projects_controller.js
const db = require("../model/index");
const project = db.project;
// Create and Save a new project
exports.create = (req, res) => {
// Validate request
if (!req.body.title) {
res.status(400).send({ message: "Content can not be empty!" });
return;
}
// Create a project
const Project = new project({
project_title: req.body.project_title,
description: req.body.description
});
// Save project in the database
Project
.save(Project)
.then(data => {
res.send(data);
})
.catch(err => {
res.status(500).send({
message:
err.message || "Some error occurred while creating the Project."
});
});
};
routes.js
module.exports = app => {
const projects = require("../controller/projects_controller.js");
var router = require("express").Router();
// Create a new project
router.post("/", projects.create);
app.use('/api/projects', router);
};
I found the problem.
[![problem][1]][1]
See that return symbol, I found out 4 days later that means there is 2 lines or more. Meaning postman was sending 2 lines instead of one. With no error message
[1]: https://i.stack.imgur.com/VVlha.jpg
I have created an express server in my server.js file, and I export app from it.
//server.js
require("dotenv").config();
const express = require("express");
const app = express();
const connectToDb = require("./connectToDb")
connectToDb().catch(console.dir)
app.use((req, res) => {
res.status(404).send("unable to find");
});
module.exports = app
I import app from server.js in the connectToDb.js file
//connectToDb.js
const app = require("./server")
const MongoClient = require("mongodb").MongoClient;
const client = new MongoClient(process.env.MONGO_URI, {
useNewUrlParser: true,
useUnifiedTopology: true
});
const port = process.env.PORT || 3000;
const connectToDb = async () =>{
try {
await client.connect();
console.log("Connected correctly to server");
app.listen(port, () => {
console.log(`Listening on port ${port}`);
})
} catch (err) {
console.log(err.stack);
} finally {
await client.close();
console.log("hello")
}
}
module.exports = connectToDb
It connects succesfully to the database, but when it reaches app.listen it gives me this error: TypeError: app.listen is not a function. I don't know why it gives me an error because I have exported app. What am I doing wrong?
That's because you have a cyclic dependency. The two files import each other, and inside server.js you make a call immediately on load. In the moment you call connectToDb inside of server.js, the server.js file has not fully executed yet and hence the module export has not yet happened. Either way it's something you should try to avoid (cyclic dependencies).
Just resolve the cycle by passing the app to the connectToDb function as a parameter instead of importing it:
//server.js
require("dotenv").config();
const express = require("express");
const app = express();
const connectToDb = require("./connectToDb")
connectToDb(app).catch(console.dir)
app.use((req, res) => {
res.status(404).send("unable to find");
});
module.exports = app
// connectToDb.js
const MongoClient = require("mongodb").MongoClient;
const client = new MongoClient(process.env.MONGO_URI, {
useNewUrlParser: true,
useUnifiedTopology: true
});
const port = process.env.PORT || 3000;
const connectToDb = async (app) =>{
try {
await client.connect();
console.log("Connected correctly to server");
app.listen(port, () => {
console.log(`Listening on port ${port}`);
})
} catch (err) {
console.log(err.stack);
} finally {
await client.close();
console.log("hello")
}
}
module.exports = connectToDb
I cloaned this code on youtube, it has Cannot GET /upload error.
I search google about this error, and many say it looks like app.get('/upload') missing problem.
But I don't know how to fix this code.
Can you tell me how to fix it?
const ipfsClient = require('ipfs-http-client');
const express = require('express');
const bodyParser = require('body-parser');
const fileupload = require('express-fileupload');
const fs = require('fs');
const ipfs = new ipfsClient(
{host:'localhost',
port:'5001',
protocol:'http'
});
const app = express();
app.engine('ejs',require('ejs').__express);
app.set('view engine','ejs');
app.use(bodyParser.urlencoded({extended:true}));
app.use(fileupload());
app.get('/',(req,res)=>{
res.render('home');
});
**app.post('/upload', (req,res)=>{
const file = req.files.file;
const fileName = req.body.fileName;
const filePath = 'files/' + fileName;
file.mv(filePath, async(err) => {
if (err){
console.log('Error failed to download the file');
return res.status(500).send(err);
}
const fileHash = await addFile(fileName, filePath);
fs.unlink(filePath, (err)=>{
if(err) console.log(err);
});
res.send(fileHash);
});
});**
*const addFile = async(fileName, filePath) =>{
const file = fs.readFileSync(filePath);
const fileAdded = await ipfs.add({path:fileName,content:file});
const fileHash = fileAdded[0].hash;
return fileHash;
};*
Since the /upload route is specified for POST method:
app.post('/upload', (req,res)=>{
there is no GET /upload route, which is the error you're getting.
So when calling your endpoint, you should change the method to POST
I'm learning the MERN stack and creating the typical beginner "Todo" App. When I make an axios call such as axios.post("http://localhost:4000/todos/add", newTodo) it posts fine, but when I try axios.post("/todos/add", newTodo) it doesn't.
The call obviously only works locally - how do I fix this/what am I doing wrong?
Here is todos.js file located in /routes/api folder:
const todoRouter = require("express").Router();
let Todo = require('../../models/todo');
todoRouter.route("/").get(function (req,res){
Todo.find(function(err, todos){
if (err){
console.log (err)
} else {
res.json(todos)
}
});
});
todoRouter.route("/:id").get(function(req,res){
let id = req.params.id
Todo.findById(id, function(err,todo){
if (err) {
console.log(err)
} else {
res.json(todo)
}
});
});
todoRouter.route("/add").post(function(req,res){
let todo = new Todo(req.body)
todo.save()
.then(function (todo){
res.status(200).json({"todo": "todo added successfully"})
})
.catch(function (err){
res.status(400).json("adding new todo failed")
})
})
todoRouter.route('/update/:id').post(function(req, res) {
Todo.findById(req.params.id, function(err, todo) {
if (!todo)
res.status(404).send("data is not found");
else
todo.todo_description = req.body.todo_description;
todo.todo_responsible = req.body.todo_responsible;
todo.todo_priority = req.body.todo_priority;
todo.todo_completed = req.body.todo_completed;
todo.save().then(todo => {
res.json('Todo updated!');
})
.catch(err => {
res.status(400).send("Update not possible");
});
});
});
module.exports = todoRouter;
Here is my index.js located in /routes/api folder:
const router = require("express").Router();
const todoRoutes = require("./todos");
// Todo routes
router.use("/todos", todoRoutes);
module.exports = router;
Here is index.js located in the /routes folder:
const path = require("path");
const router = require("express").Router();
const todoRoutes = require("./api");
// API Routes
router.use(todoRoutes);
// If no API routes are hit, send the React app
router.use(function(req, res) {
res.sendFile(path.join(__dirname, "../client/build/index.html"));
});
module.exports = router;
Here is my server.js file:
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const cors = require('cors');
const mongoose = require('mongoose')
const PORT = process.env.PORT || 4000;
const routes = require('./routes')
// Define middleware here
app.use(cors());
app.use(express.urlencoded({ extended: true }));
app.use(bodyParser.json());
// Serve up static assets (usually on heroku)
if (process.env.NODE_ENV === "production") {
app.use(express.static("client/build"));
}
// Define API Routes
app.use(routes)
// Send every other request to the React app
// Define any API routes before this runs
app.get("*", (req, res) => {
res.sendFile(path.join(__dirname, "./client/build/index.html"));
});
//Connect to mongoose
mongoose.connect(process.env.MONGODB_URI || "mongodb://127.0.0.1:27017/todos", { useNewUrlParser: true });
const connection = mongoose.connection
connection.once("open", function () {
console.log("MongoDB database connection established successfully")
})
app.listen(PORT, function () {
console.log("Server is running on Port: " + PORT);
});
Just set "proxy": "http://localhost:4000" property in your package.json and all your /something requests will be directed towars your backend without having to specify the base url
you can set the baseUrl for axios to http://localhost:4000 and then relative paths should work. https://github.com/axios/axios#creating-an-instance
I am creating nodejs backend app with postgresql database. What I want is when once I create connection to database in my db.js file, that I can reuse it in other files to execute queries.
This is my db.js file
const pool = new Pool({
user: 'us',
host: 'localhost',
database: 'db',
password: 'pass',
port: 5432,
})
pool.on('connect', () => {
console.log('connected to the Database');
});
module.exports = () => { return pool; }
And this is how I tried to use it in index.js file
const db = require('./db.js')
app.get('/', (request, response) => {
db().query('SELECT * FROM country'), (error, results) => {
if (error) {
response.send(error)
}
console.log(results)
response.status(201).send(results)
}
})
There aren't any errors, and when I go to this specific page, it's keep loading. Nothing in console also.
But, if I write a function in my db.js file and do something like pool.query(...), export it, and in my index.js I write app.get('/', exportedFunction), everything is working fine.
Is there any way not to write all my (like 50) queries in just one (db.js) file, because I want to organise my project a little bit?
To streamline your project structure entirely, if you're starting from scratch maybe try this :
index.js
const express = require('express');
const app = express();
const PORT = 8080;
const bodyparser = require('body-parser');
const baseRouter = require('../your-router');
app.use(bodyparser.json());
app.use(express.json());
app.use('/', baseRouter);
app.listen(PORT, function () {
console.log('Server is running on PORT:', PORT);
});
your-router.js
const Router = require('express');
const router = Router();
const getCountries = require('../handlers/get');
router.get('/check-live', (req, res) => res.sendStatus(200));
// route for getCountries
router.get('/countries', getCountries);
src/handler/get.js
const YourService = require('./service/your-service');
function getCountries(request, response) {
const yourService = new YourService();
yourService.getCountries(request)
.then((res) => { response.send(res); })
.catch((error) => { response.status(400).send({ message: error.message }) })
}
module.exports = getCountries;
src/service/your-service.js
const connectionPool = require('../util/dbConnect');
class yourService {
getCountries(req) {
return new Promise(((resolve, reject) => {
connectionPool.connect((err, db) => {
if (err) reject(err);
let query = format('SELECT * FROM country'); // get inputs from req
db.query(query, (err, result) => {
if (err) reject(err);
resolve(result);
})
});
}));
}
}
module.exports = yourService;
dbConnect.js
const pgCon = require('pg')
const PGUSER = 'USER'
const PGDATABASE = 'localhost'
let config = {
user: PGUSER,
database: PGDATABASE,
max: 10,
idleTimeoutMillis: 30000
}
let connectionPool = new pgCon.Pool(config);
module.exports = connectionPool;
Please consider this as a basic example, refactor your code to use callbacks/async awaits (in the above example you can just use callbacks not needed to convert into promise), if needed - you can have DB-layer calls from the service layer in order to extract DB methods from the service layer.