Node Express Mongo app goes sleep mode in shared cPanel - node.js

I deployed a Node js server with Express Js and MongoDB on NameCheap cPanel. The problem is I have to refresh 2 or 3 times to get the data from the server.Otherwise its gives 404. Then it works fine but after some minutes it acts the same. I have to refresh 2 or 3 times.
`
const express = require("express");
const { MongoClient } = require("mongodb");
const cors = require("cors");
require("dotenv").config();
const app = express();
const port = process.env.PORT || 5000;
//Middleware
app.use(cors());
app.use(express.json());
//MongoDB linking
const uri = `mongodb+srv://${process.env.DB_USER}:${process.env.DB_PASS}#xyz`;
const client = new MongoClient(uri);
async function run() {
try {
await client.connect();
//DB Folder and Subfolder
const database = client.db("XYZ");
const allUsers = database.collection("All-Users");
app.get("/allusers", async (req, res) => {
const get = allUsers.find({});
const allData = await get.toArray();
res.send(allData);
});
} finally {
//await client.close();
}
}
run().catch(console.dir);
app.get("/", (req, res) => {
res.send(" Server is running just fine");
});
app.listen(port, () => {
console.log(" server running on port :", port);
});
`
I dont have idea what the problem is. Did anyone faced the same issue, and solved the issue?
Thank you.

Related

Express JS app showing cannot find after deployment on cPanel while working fine on local

Express App showing cannot find after deploying on cPanel. I have tried to sort out this issue also when I write server.listen() it works great but when I write app.listen() it gives cannot find message.
I tried default Node Js code (last 10 lines except app.listen() ) which works fine while app.listen() not working:
const express = require("express");
const multiparty = require('multiparty');
const mongoose = require("mongoose");
const morgan = require('morgan');
const { createHttpTerminator } = require('http-terminator');
const fs = require('fs');
const cors = require('cors');
const crypto = require('crypto');
require('dotenv').config();
const { MongoClient, ServerApiVersion } = require('mongodb');
const {Product, Service, Home, HireMe } = require('./models/Product');
const app = express();
app.use(morgan('tiny'));
app.use(express.static('public'));
app.use(express.json());
app.use(cors());
app.get('/', (req, res) => {
res.send('Home Page...!');
});
app.get('/offers', async (req, res) => {
try {
const result = await Product.find({});
res.send("result");
} catch (err) {
res.send({ 'error': err.message });
}
})
var http = require('http');
var server = http.createServer(function(req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
var message = 'It works!\n',
version = 'NodeJS ' + process.versions.node + '\n',
response = [message, version].join('\n');
res.end(app);
});
server.listen(); //It works
app.listen (); // Showing Cannot find message
I solved this error by prefixing the URL link (on which I created node JS on cPanel) to routes. Now it works great.

404 Not Found when requesting after deploying to Heroku, works locally

I have been working all day on trying to deploy my MERN stack app to Heroku. So far it works perfectly fine if I run it locally. The app gets deployed on Heroku, but when I try to submit/get items from MongoDB Atlas, I get a 404 error.
I tried removing the Proxy in package.json, didn't work. I ran a build command and the file is in the correct place, still doesn't work. I'm really clueless about what could be going on..
Here is the code:
BACKEND:
index.js
const express = require('express');
const app = express();
const cors = require('cors');
const mongoose = require('mongoose');
require('dotenv').config();
app.use(cors());
app.use(express.static('build'));
app.use(express.json({ limit: '50mb' }));
app.use(express.urlencoded({ limit: '50mb' }));
const uri =
'mongodb+srv://db:passwordhere#cluster0.fgryd.mongodb.net/myFirstDatabase?retryWrites=true&w=majority';
mongoose.connect(uri);
const profileSchema = new mongoose.Schema({
..
..
..
});
const Profile = mongoose.model('Profile', profileSchema);
module.exports = mongoose.model('Profile', profileSchema);
profileSchema.set('toJSON', {
transform: (document, returnedObject) => {
returnedObject.id = returnedObject._id.toString();
delete returnedObject._id;
delete returnedObject.__v;
},
});
app.get('/api/profiles', (req, res) => {
Profile.find({}).then(profiles => {
res.json(profiles);
});
});
app.post('/api/profiles', (request, response) => {
const body = request.body;
if (!body) {
return response.status(400).json({
error: 'content missing',
});
}
const profile = new Profile({
...
...
...
});
profile.save().then(savedProfile => {
response.json(savedProfile);
});
});
const PORT = process.env.NODE_ENV || 3001;
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
My Frontend:
App.js
function App() {
const [viewProfile, setViewProfile] = useState(false);
const [formState, setFormState] = useState(1);
const [prof, setProf] = useState([]);
const handleProfile = () => {
setViewProfile(!viewProfile);
};
const fetchData = async () => {
await axios.get('/api/profiles').then(res => setProf(res.data));
};
useEffect(() => {
fetchData();
}, []);
const addProfile = async data => {
let img = await ImgToBase64(data.profImg);
await axios.post('/api/profiles', {
...
...
...
});
fetchData();
alert(`success!`);
};
return (
<ChakraProvider>
...
...
...
</ChakraProvider>
);
}
Can I please get some help? I almost tried everything
Heroku offers you a node's container instead of VPS (Virtual Private Server).
Inside their servers, there are more than 10k apps running on a VM. They are mapping your app port with their subdomain. for that, you have to feed port configurations to your application.
In your code, there is process.env.NODE_ENV but in the Heroku environment, they are using process.env.PORT.
const PORT = process.env.PORT || 3001;
Also, you need to add a start script in your package.json.
start: "node index.js"
if your main file is not is the index.js, you can replace your script name with main script name
You can try these two things.
Change your PORT name.
https://devcenter.heroku.com/articles/getting-started-with-nodejs#push-local-changes
Your code:
const PORT = process.env.NODE_ENV || 3001;
After
const PORT = process.env.PORT || 3001;
Make sure you created Procfile with text "web: npm start" in the file.
https://devcenter.heroku.com/articles/getting-started-with-nodejs#define-a-procfile
Procfile

Can't retrieve information from mongodb when deploying on heroku

The problem is as the title suggests. When I run my app locally, I'm able to retrieve information from MongoDB but on Heroku, undefined is returned. Should I connect to MongoDB in another way because if I hardcode some text everything works just fine. Here are my scripts:
function to get data
const MongoClient = require("mongodb").MongoClient;
const dbConnectionUrl = "mongodb+srv://xxxxxxx#cluster0.ro4dz.mongodb.net/data?retryWrites=true&w=majority";
const saySomething = (req, res, next) => {
// res.status(200).json({
// body: 'Hello from the server!'
// });
login()
.then(val=>res.send(val))
};
async function login(){
const client = new MongoClient(dbConnectionUrl)
try{
await client.connect();
const database = client.db("data");
const movies = database.collection("movies");
const query = { name: "toke" };
const movie = await movies.findOne(query);
return movie
}catch(err){
console.log(err)
}
}
module.exports.saySomething = saySomething;
router
const express = require('express');
const router = express.Router();
const controllers = require('./../controllers/controllers');
router.get('/say-something', controllers.saySomething);
module.exports = router;
server
// Import dependencies
const express = require('express');
const cors = require('cors');
const path = require('path');
// Create a new express application named 'app'
const app = express();
// Set our backend port to be either an environment variable or port 5000
const port = process.env.PORT || 5000;
// This application level middleware prints incoming requests to the servers console, useful to see incoming requests
app.use((req, res, next) => {
console.log(`Request_Endpoint: ${req.method} ${req.url}`);
next();
});
// Configure the CORs middleware
// Require Route
app.use(cors());
const api = require('./routes/routes');
// Configure app to use route
app.use('/api', api);
// This middleware informs the express application to serve our compiled React files
if (process.env.NODE_ENV === 'production' || process.env.NODE_ENV === 'staging') {
app.use(express.static(path.join(__dirname, 'client/build')));
app.get('*', function (req, res) {
res.sendFile(path.join(__dirname, 'client/build', 'index.html'));
});
};
// Catch any bad requests
app.get('*', (req, res) => {
res.status(200).json({
msg: 'Catch All'
});
});
// Configure our server to listen on the port defiend by our port variable
app.listen(port, () => console.log(`BACK_END_SERVICE_PORT: ${port}`));
front
import { useEffect, useState } from 'react';
import './App.css';
import axios from 'axios'
function App(){
useEffect(()=>{
get()
})
const[text, settext] = useState('')
async function get(){
let request = await axios.get('/api/say-something')
console.log(request.data.name)
settext(request.data.name)
}
return(
<div>{text}</div>
)
}
export default App;
I solved the issue! The first thing I did was that I added MongoDB connection URI as an environmental variable in my app via Heroku. Secondly, I added an option in MongoDB so that the cluster can be accessed from any computer. By default, the access is set to the local computer so I added another IP, namely 0.0.0.0/0 to my cluster, and now everything works just fine.

How I can do a module.exports for a Pool of Postgres

I have been getting a problem when I want to module.export the pool variable to use it in other files. I have this program in src\db\index.js:
const {Pool} = require('pg');
const express = require('express');
//Initialize
const path = require('path');
const app = express();
const fetch = require('fetch');
const PORT = process.env.PORT || 5000;
//Global Variables
const pool = new Pool({
connectionString: process.env.DATABASE_URL,
ssl:true
});
//Setting
app.use(express.static(path.join(__dirname, 'public')));
//Routes
app.use(require('../Routes/logIn'));
app.use(require('../Routes/singIn'));
app.use(require('../Routes/forgotPass.js'));
app.listen(PORT, () => console.log(`Listening on ${PORT}`));
module.exports = pool;
And then I want to require the const pool in this file src\Routes\LogIn.js:
const express = require('express');
const pool = require('../db');
const router = express.Router();
router.get('/usuario/:user', function (req, res) {
//console.log("GET usuario");
var user = req.params.user;
pool.query(
`select * from users where email = '${user}' limit 1`,
function (error, resq, fields) {
if (error) {
console.log(error);
} else {
console.log(user);
res.send(resq.rows);
}
}
);
});
module.exports = router;
But when I run the index.js and go to the route ulr/usuario/:user, in the logs I see that the program has an error that says "pool.query is not a function". I want to know how i could export the const pool to use it in other files.
You can use
module.exports = {
query: (text, params) => pool.query(text, params),
}
Use express-promise-router
const Router = require('express-promise-router')
const db = require('../db')
const router = new Router()
Use
await db.query(`
SELECT * from local
`)
instead of pool.query in your router.get or router.post
The above should solve your issue - You can check the same reference here
https://node-postgres.com/guides/async-express

Cannot connect to MongoDB via env variable

I am trying to conceal my connection string, so I installed env2 in my project. Then I made a config.env file that keeps my connection string like this:
export DB_URL='mongodb://user:userPassword#ds241968.mlab.com:41968/heroku_hc9xjmcl'
However when I use that variable as a connection string I cannot connect to Mlab I get the following error:
UnhandledPromiseRejectionWarning: MongoNetworkError: failed to connect to server [ds241968.mlab.com:41968] on first connect [MongoError: Authentication failed.]
But when I try to connect only with the string without using env2 I connect perfectly, so why does the ahuthentication fail when I use a env variable and how can I connect with one properly? Here is my server.js:
// Requiring the dependencies
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 || 3009;
const itemRoutes = express.Router();
let Comment = require('./comment.model');
const env = require('env2')('../config.env');
console.log(process.env.DB_URL)
app.use(cors());
app.use(bodyParser.json());
const { DB_URL } = process.env;
mongoose.connect( DB_URL , { useNewUrlParser: true } )
const connection = mongoose.connection;
connection.once('open', function() {
console.log('Connection to MongoDB established succesfully!');
});
// Serve static assets
if(process.env.NODE_ENV === 'production') {
app.use(express.static('build'));
}
itemRoutes.route('/').get( async (req, res) => {
let collection = connection.collection("posts");
let response = await collection.find({})
.toArray();
res.send(response);
});
itemRoutes.route('/comments').get( async (req, res) => {
let collection = connection.collection("comments");
let response = await collection.find({})
.toArray();
res.send(response);
});
itemRoutes.route('/userComments')
.post((req, res) => {
res.setHeader('Content-Type', 'application/json');
let comment = new Comment(req.body);
comment.save()
.then(comment => {
res.status(200).json({comment})
})
.catch(err => {
res.status(400).send('failed')
})
});
app.use('/', itemRoutes);
app.use('/userComments', itemRoutes);
app.listen(PORT, function() {
console.log('Server is running on' + ' ' + PORT);
})
Looks like you are using Node and Heroku. In that case,
You should set Heroku Config Vars (you can do this either via CLI or your Heroku Dashboard)
Refer to the config var in your node application the same way you are referring to now.
Remove 'env2' related code as you won't need it for this purpose
For example, if you create Heroku config var called "MONGO_URI", refer to it as process.env.MONGO_URI in your node application.
Details can be found here: https://devcenter.heroku.com/articles/config-vars#managing-config-vars

Resources