I can't connect to MongoDB using mongoose - node.js

I keep getting a error "MongooseError: The uri parameter to openUri() must be a string, got "undefined". Make sure the first parameter to mongoose.connect() or mongoose.createConnection() is a string.". I've been looking at other questions that get a similar error butI did not find a solution after trying multiple different things.
in package.json
{
"dependencies": {
"bcrypt": "^5.1.0",
"body-parser": "^1.20.1",
"cors": "^2.8.5",
"dotenv": "^16.0.3",
"express": "^4.18.2",
"gridfs-stream": "^1.1.1",
"helmet": "^6.0.1",
"jsonwebtoken": "^9.0.0",
"mongoose": "^6.7.0",
"morgan": "^1.10.0",
"multer": "^1.4.4",
"multer-gridfs-storage": "^5.0.2"
},
"name": "server",
"version": "1.0.0",
"main": "index.js",
"type": "module",
"devDependencies": {},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": ""
}
in index.js
import express from "express";
import bodyParser from "body-parser";
import mongoose from "mongoose";
import cors from "cors";
import dotenv from "dotenv";
import multer from "multer";
import helmet from "helmet";
import morgan from "morgan";
import path from "path";
import { fileURLToPath } from "url";
/* CONFIGURATIONS */
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
dotenv.config();
const app = express();
app.use(express.json());
app.use(helmet());
app.use(helmet.crossOriginResourcePolicy({ policy: "cross-origin" }));
app.use(morgan("common"));
app.use(bodyParser.json({ limit: "30mb", extended: true }));
app.use(bodyParser.urlencoded({ limit: "30mb", extended: true }));
app.use(cors());
app.use("/assets", express.static(path.join(__dirname, "public/assets")));
/* FILE STORAGE */
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, "public/assets");
},
filename: function (req, file, cb) {
cb(null, file.originalname);
},
});
const upload = multer({ storage });
/* MONGOOSE SETUP */
const PORT = process.env.PORT || 6001;
mongoose
.connect(process.env.MONGO_URL, {
useNewUrlParser: true,
useUnifiedTopology: true,
})
.then(() => {
app.listen(PORT, () => console.log(`Server Port: ${PORT}`));
})
.catch((error) => console.log(`${error} did not connect`));
in .env
MONGO_URL = 'the connection string'
PORT = 3001

Related

I am trying to deploy MERN App on VERCEL but getting NOT FOUND

I am trying to deploy MERN App on Vercel but getting NOT FOUND
When i put NODE_ENV as PRODUCTION then it works fine and serves the static files on local machine when run npm start but it is not working on vercel.
.
My Directory Structure is
My app.js file is
const express = require("express");
const app = express();
const dotenv = require("dotenv");
const mongoose = require("mongoose");
const PostRoutes = require("./Routes/posts");
const CategoryRoutes = require("./Routes/categories");
const UserRoutes = require("./Routes/user");
const AuthRoutes = require("./Routes/auth");
const bodyParser = require("body-parser");
const multer = require("multer");
var storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, "uploads/images/");
},
filename: (req, file, cb) => {
cb(null, Date.now() + "_" + file.originalname);
},
});
var upload = multer({ storage: storage });
const cors = require("cors");
dotenv.config();
app.use(express.json());
app.use("uploads/images/", express.static("uploads/images/"));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cors());
if (process.env.NODE_ENV == "production") {
const path = require("path");
app.get("/", (req, res) => {
app.use(express.static(path.resolve(__dirname, "frontend", "build")));
res.sendFile(path.resolve(__dirname, "frontend", "build", "index.html"));
});
}
mongoose
.connect(process.env.MONGO_URL, {
useNewUrlParser: true,
useUnifiedTopology: true,
})
.then(console.log("connected to Mongo database "))
.catch((err) => {
console.log(err);
});
app.use("/api/posts", upload.single("photo"), PostRoutes);
app.use("/api/categories", CategoryRoutes);
app.use("/api/auth", upload.none(), AuthRoutes);
app.use("/api/users", upload.single("profile_pic"), UserRoutes);
app.listen(process.env.PORT || 3001, () => {
console.log(`Server Listening on the port ${process.env.PORT}`);
});
package.json file
{
"name": "backend",
"version": "1.0.0",
"description": "Backend to the blog app ",
"main": "app.js",
"scripts": {
"start": "node app.js",
"dev-start": "nodemon app.js --ignore client",
"start-client": "npm start --prefix frontend",
"dev": "concurrently \"cd ./frontend && npm start\" \"npm run dev-start\""
},
"author": "Shiv Shankar Prasad",
"license": "MIT",
"dependencies": {
"bcryptjs": "^2.4.3",
"body-parser": "^1.20.0",
"concurrently": "^7.4.0",
"cookie-parser": "^1.4.6",
"cors": "^2.8.5",
"dotenv": "^16.0.1",
"express": "^4.18.1",
"express-async-handler": "^1.2.0",
"express-validator": "^6.14.2",
"jsonwebtoken": "^8.5.1",
"minifaker": "^1.34.1",
"mongoose": "^6.5.3",
"multer": "^1.4.5-lts.1",
"nodemon": "^2.0.19"
}
}
Please help.
I have found a solution and it was the changes in the vercel.json file.
Now i used the vercel CLI and it is much more easy to use.
{
"version": 2,
"builds": [
{
"src": "./index.js",
"use": "#vercel/node"
}
],
"routes": [
{
"src": "/(.*)",
"dest": "/"
}
]
}

Unable to deploy my node.js server via Heroku error heroku[router]: at=error code=H10

I followed a YouTube tutorial and created a full stack (MERN) social media application. I am having issues deploying it. I have tried every solution I could find related to heroku[router] code=H10, but none of them solved my issues. Here are my files related.
package.json
{
"name": "server",
"version": "1.0.0",
"description": "",
"main": "index.js",
"type": "module",
"scripts": {
"start": "node index.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"bcrypt": "^5.0.1",
"body-parser": "^1.20.0",
"cors": "^2.8.5",
"dotenv": "^16.0.1",
"express": "^4.18.1",
"jsonwebtoken": "^8.5.1",
"mongoose": "^6.5.1",
"multer": "^1.4.5-lts.1",
"nodemon": "^2.0.19"
}
}
index.js
import express from "express";
import bodyParser from "body-parser";
import mongoose from "mongoose";
import dotenv from "dotenv";
import cors from "cors";
import AuthRoute from "./Routes/AuthRoute.js";
import UserRoute from "./Routes/UserRoute.js";
import PostRoute from "./Routes/PostRoute.js";
import UploadRoute from "./Routes/UploadRoute.js";
// Routes
const app = express();
//Public images
app.use(express.static('public'))
app.use('/images', express.static('images'))
// Middleware
app.use(bodyParser.json({ limit: "30mb", extended: true }));
app.use(bodyParser.urlencoded({ limit: "30mb", extended: true }));
app.use(cors());
dotenv.config();
mongoose
.connect(process.env.MONGO_URI, {
useNewUrlParser: true,
useUnifiedTopology: true,
})
.then(() =>
app.listen(process.env.PORT, () =>
console.log("Connected")
)
)
.catch((error) => console.log(error));
// Usage of routes
app.use("/auth", AuthRoute);
app.use("/user", UserRoute);
app.use("/posts", PostRoute);
app.use('/upload', UploadRoute);
I have also edited the config variables and have
MONGO_URI linked to my MongoDB.
I originally had my start script as nodemon index.js. I changed it to direct node to start at index.js. Perhaps that is part of the issue. I changed it to just run node instead of nodemon.
What am I doing wrong?

React / React-Router/ Express / Heroku routing issue

I've deployed a React/Express app on Heroku. I'm using BrowserRouter. Everything worked fine locally. My issue is the backend routes are not working. The only route that works is the catchall route. The catchall route is also being called three times for some reason. I console logged the request path using 'req.path' to see which path was being called. It should have been '/google'. Instead the three calls give three different logs for req.path. They are: '/static/css/main.814455d3.chunk.css.map', '/static/js/main.06bdb7f0.chunk.js.map', '/static/js/1.1baafe13.chunk.js.map'. I'm hoping someone can help.
I've been stuck for over a day now. Here are my package.json and static.json from the client side:
static.json
{
"root": "build/",
"clean_urls": false,
"routes": {
"/**": "index.html"
}
}
package.json
{
"name": "workout_tracker",
"version": "0.1.0",
"private": true,
"dependencies": {
"axios": "^0.18.0",
"jw-paginate": "^1.0.2",
"jw-react-pagination": "^1.0.7",
"normalize.css": "^8.0.0",
"query-string": "^6.2.0",
"random-id": "0.0.2",
"react": "^16.5.2",
"react-dom": "^16.5.2",
"react-headroom": "^2.2.2",
"react-icons-kit": "^1.1.6",
"react-redux": "^5.0.7",
"react-router-dom": "^4.3.1",
"react-scripts": "^2.0.5",
"react-swipe-to-delete-component": "^0.3.4",
"react-swipeout": "^1.1.1",
"redux": "^4.0.0",
"redux-thunk": "^2.3.0"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
},
"devDependencies": {
"redux-devtools-extension": "^2.13.5"
},
"proxy":"localhost:4000",
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
]
}
And this is my package.json from express
{
"name": "expresstest",
"version": "1.0.0",
"description": "app to test express and mysql",
"main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start":"node app.js",
"heroku-postbuild": "cd client && npm install && npm run build"
},
"author": "",
"license": "ISC",
"dependencies": {
"body-parser": "^1.18.3",
"connect-flash": "^0.1.1",
"cookie-session": "^2.0.0-beta.3",
"cors": "^2.8.4",
"express": "^4.16.3",
"mysql": "^2.16.0",
"passport": "^0.4.0",
"passport-google-oauth20": "^1.0.0"
}
}
This is part of the code from the server. I omitted the other routes as none besides the catchall route are being called anyway.
let express = require("express");
let cors= require("cors");
let mysql = require("mysql");
const util = require("util");
const keys = require("./config/keys");
const passport = require("passport");
const passportSetup = require("./config/passport-setup");
const bodyParser = require("body-parser");
const flash= require("connect-flash");
const path= require("path");
console.log("process env");
console.log("-------");
console.log(process.env.PWD);
const cookieSession = require("cookie-session");
let app = express();
app.use(bodyParser.json());
app.use(cookieSession({
maxAge:24 * 60 * 60 * 1000,
keys:[keys.session.cookieKey]
}));
app.use(passport.initialize());
app.use(passport.session());
if (process.env.NODE_ENV === 'production') {
console.log("inside prod");
app.use(express.static('client/build'));
}
let connection =keys.connection;
app.get("/google", passport.authenticate("google",{
scope:['profile'],
failureFlash:"failure"
}),(req,res)=>{
// console.log(req.flash());
console.log("/google route");
});
const port = process.env.PORT || 4000;
let http = require("http");
let server = http.createServer(app,(req,res)=>{
res.writeHead(200, {"Access-Control-Allow-Origiin": "*"})
});
app.get('/*', (req, res) => {
console.log("catchall");
console.log(req.hostname);
console.log(req.path);
console.log(path.join(__dirname + '/client', 'build', 'index.html'));
res.sendFile(path.join(__dirname + '/client', 'build', 'index.html'));
})
server.listen(port, ()=>{
console.log("Listening on "+ port)
});
Here is my folder structure:
Link to pic of my folder structure
EDIT: I got it working, here is the code that works. I don't know why it works, though. I just tried some things I found on blogs for React/Express/Heroku projects. If anyone can tell me why it works it would be greatly appreciated.
let express = require("express");
let cors= require("cors");
let mysql = require("mysql");
const util = require("util");
const keys = require("./config/keys");
const passport = require("passport");
const passportSetup = require("./config/passport-setup");
const bodyParser = require("body-parser");
const flash= require("connect-flash");
const path= require("path");
console.log("process env");
console.log("-------");
console.log(process.env.PWD);
const cookieSession = require("cookie-session");
let app = express();
app.use(bodyParser.json());
app.use(express.static(__dirname));
app.use(cookieSession({
maxAge:24 * 60 * 60 * 1000,
keys:[keys.session.cookieKey]
}));
app.use(passport.initialize());
app.use(passport.session());
if (process.env.NODE_ENV === 'production') {
console.log("inside prod");
app.use(express.static('client/build'));
}
let connection =keys.connection;
app.get("/google", passport.authenticate("google",{
scope:['profile'],
failureFlash:"failure"
}),(req,res)=>{
// console.log(req.flash());
console.log("/google route");
});
const port = process.env.PORT || 4000;
let http = require("http");
let server = http.createServer(app,(req,res)=>{
res.writeHead(200, {"Access-Control-Allow-Origiin": "*"})
});
app.get("/service-worker.js", (req, res) => {
res.sendFile(path.join(__dirname + "/client","build", "service-worker.js"));
});
app.get('/*', (req, res) => {
console.log("catchall");
console.log(req.hostname);
console.log(req.path);
console.log(path.join(__dirname + '/client', 'build', 'index.html'));
res.sendFile(path.join(__dirname + '/client', 'build', 'index.html'));
})
server.listen(port, ()=>{
console.log("Listening on "+ port)
});

sass-node-middleware not working

I'm using sass with node app, for that I have installed this dependency "npm install node-sass-middleware". It's not generating the style.css file means not compiling the style.scss file. And I'm using express. Please help
Code in my app.js
app.use(sassMiddleware({
src: path.join(__dirname, 'public/scss'),
dest: path.join(__dirname, 'public/css'),
debug: true,
indentedSyntax: true,
outputStyle: 'compressed'
}));
// Static folder
app.use(express.static(path.join(__dirname, 'public')));
thanks in advance
app.js
var express = require('express');
var sass = require('node-sass');
var sassMiddleware = require('node-sass-middleware');
var path = require('path');
const app = express();
app.set('view engine', 'ejs');
app.use(sassMiddleware({
src: path.join(__dirname, 'public/scss'),
dest: path.join(__dirname, 'public/css'),
debug: true,
indentedSyntax: false,
outputStyle: 'compressed',
prefix: '/css'
}));
// Static folder
app.use(express.static(path.join(__dirname, 'public')));
app.get('/', (req,res)=>{
res.render('index');
});
app.get('/download', function (req, res, next) {
var filePath = "public/files/Bijitashya (2).doc"; // Or format the path using the `id` rest param
var fileName = "Bijitashya (2).doc"; // The default name the browser will use
res.download(filePath, fileName);
});
const port = process.env.PORT || 5000;
app.listen(port, () =>{
console.log(`Server started on port ${port}`);
});
package.json
{
"name": "portfolio",
"version": "1.0.0",
"description": "My Portfolio",
"main": "app.js",
"scripts": {
"start": "node app.js"
},
"author": "Bijitashya",
"license": "ISC",
"dependencies": {
"bootstrap": "4.0.0",
"ejs": "^2.5.7",
"express": "^4.16.3",
"font-awesome": "^4.7.0",
"jquery": "^3.3.1",
"node-sass": "^4.9.0",
"node-sass-middleware": "^0.11.0",
"popper.js": "^1.12.9"
}
}
Assuming from your directory name, you have .scss files that you need to compile. With the optionindentedSyntax: true the middleware will try to find .sass files instead of .scss files. So if you don’t have any .sass files, it won’t be any output or compiled files
You just need to set the option to false or just remove the option, as false is the default value for it.

When I deploy my nodejs app on heroku, build success but got a "Application Error"

I have already run my nodejs app successfully on my localhost, but when I deploy it on heroku, build success, but I got a "Application Error", when I use "heroku logs", it show like this:
console screenshot
I can't figure out what's wrong with my app, hope to get your help, thanks!
Here's my package.json
{
"main": "index.js",
"scripts": {
"test": "mocha --harmony test",
"start": "cross-env NODE_ENV=production pm2 start index.js --node-args='--harmony' --name 'adolt-blog'"
},
...
"dependencies": {
"config-lite": "^1.5.0",
"connect-flash": "^0.1.1",
"connect-mongo": "^1.3.2",
"cross-env": "^3.1.3",
"ejs": "^2.5.2",
"express": "^4.14.0",
"express-formidable": "^1.0.0",
"express-session": "^1.14.2",
"express-winston": "^2.0.0",
"marked": "^0.3.6",
"moment": "^2.17.0",
"mongolass": "^2.3.2",
"objectid-to-timestamp": "^1.3.0",
"sha1": "^1.1.1",
"winston": "^2.3.0",
"pm2": "^2.2.3",
"mocha": "^3.2.0"
}
}
and index.js
var path = require('path');
var express = require('express');
var session = require('express-session');
var MongoStore = require('connect-mongo')(session);
var flash = require('connect-flash');
var config = require('config-lite');
var routes = require('./routes');
var pkg = require('./package');
var winston = require('winston');
var expressWinston = require('express-winston');
var app = express();
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(express.static(path.join(__dirname, 'public')));
app.use(session({
name: config.session.key,
secret: config.session.secret,
cookie: {
maxAge: config.session.maxAge
},
store: new MongoStore({
url: config.mongodb
}),
saveUninitializedSession: true,
resaveSession: true
}));
app.use(flash());
app.use(require('express-formidable')({
uploadDir: path.join(__dirname, 'public/img'),
keepExtensions: true
}));
app.locals.blog = {
// title: pkg.name,
// description: pkg.description
title: 'Adolt\'s Blog',
description: 'Learn Node.js'
};
app.use(function (req, res, next) {
res.locals.user = req.session.user;
res.locals.success = req.flash('success').toString();
res.locals.error = req.flash('error').toString();
next();
});
app.use(expressWinston.logger({
transports: [
new (winston.transports.Console)({
json: true,
colorize: true
}),
new winston.transports.File({
filename: 'logs/success.log'
})
]
}));
routes(app);
app.use(expressWinston.errorLogger({
transports: [
new winston.transports.Console({
json: true,
colorize: true
}),
new winston.transports.File({
filename: 'logs/error.log'
})
]
}));
if (module.parent) {
module.exports = app;
} else {
const port = process.env.PORT;
app.listen(port, function () {
console.log(`${pkg.name} listening on port ${port}`);
});
}
Thanks to the help of #Lucas Katayama, the problem finally solved.
First, add main.js according to the use-pm2-with-cloud-providers.
And then modify the Procfile like this
web: node main.js
Finally, rebuild your app and see if it works!
Hope it can help! Good luck!

Resources