I've set up a tiny little app which is run using Express, Nodemon and Mongoose.
A few hours ago, it worked fine - and I don't think I've changed any of the code then. If I have, it must have been accidentally.
But whenever I try to access my localhost for this particular app, it doesn't load. It just sits in this state of loading. No errors appear, the console is clear and it states 'Running on Port 3000'.
If I try other apps, they work fine on localhost, so it must be the code - but I don't even know where to start considering there's no error messages.
Here's my code:
const express = require("express");
const bodyParser = require("body-parser");
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
var encrypt = require('mongoose-encryption');
require("dotenv").config();
const app = express();
mongoose.connect(process.env.MONGO_URI, {useNewUrlParser: true, useUnifiedTopology: true});
const SubmitDebtSchema = new Schema ({
balance: [{
balanceDate: Date,
newBalance: Number
}],
monthly: Number,
date: String,
autoBalance: String
});
const encKey = process.env.ENCKEY;
const sigKey = process.env.SIGKEY;
SubmitDebtSchema.plugin(encrypt, { encryptionKey: encKey, signingKey: sigKey, excludeFromEncryption: ['autoBalance'] });
const SubmitDebt = mongoose.model('submitdebt', SubmitDebtSchema);
app.get("/", async (req, res) => {
const debts = await SubmitDebt.find({ autoBalance: true });
debts.map(debt => {
console.log(debt.id);
const debtDate = parseInt(debt.date);
const finalDate = new Date(new Date().setDate(debtDate));
console.log(finalDate);
const todaysDate = new Date();
console.log(todaysDate);
const debtBalance = debt.balance[debt.balance.length - 1].newBalance;
console.log(debtBalance);
const debtRepayment = debt.monthly;
console.log(debtRepayment);
const updatedBalance = { balanceDate: new Date(), newBalance: debtBalance - debtRepayment };
console.log(updatedBalance);
if (todaysDate < finalDate) {
console.log("Balance shouldn't change.");
}
if (todaysDate >= finalDate) {
console.log("Balance should change");
SubmitDebt.findById(debt._id, (err, submitdebt) => {
if (!submitdebt) {
console.log("Unable to find entry to edit.");
}
else {
submitdebt.balance.push(updatedBalance);
submitdebt.save().then(submitdebt => {
console.log("Debt successfully updated.");
})
.catch(err => {
console.log("Debt unsuccessfully updated.");
});
}
});
}
res.send(debts);
});
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Lemio is running on port ${ PORT }`);
});
Can anyone spot any reason why my localhost isn't working for this app? Feel like I'm missing something obvious!
Some thoughts:
kill the process and start it over;
check if your port is busy with some other app;
check is mongod is running.
Links:
How To Use ps, kill, and nice to Manage Processes in Linux
How to check if port is in use on Linux or Unix
Manage mongod Processes
Related
Ive managed to slowly grind my way through the curriculum and just completed the backend portion.
I decided to look into building some practice project using Heroku…
If this is not the place to post his please let me know.
While following this tutorial https://devcenter.heroku.com/articles/getting-started-with-nodejs, I get to the portion where we connect to the Postgres server (‘Provision a database’). I do this successfully but I get side tracked on figuring out how to access/use this Postgres database locally when it is located and provided through Heroku. Please consider the following two methods:
Method #1
const cool = require("cool-ascii-faces");
const express = require("express");
const path = require("path");
const PORT = process.env.PORT || 5000;
const { Pool } = require("pg");
const pool = new Pool({
connectionString: process.env.DATABASE_URL,
ssl: {
rejectUnauthorized: false,
},
});
express()
.use(express.static(path.join(__dirname, "public")))
.set("views", path.join(__dirname, "views"))
.set("view engine", "ejs")
.get("/", (req, res) => res.render("pages/index"))
.get("/db", async (req, res) => {
try {
const client = await pool.connect();
const result = await client.query("SELECT * FROM test_table");
const results = { results: result ? result.rows : null };
res.render("pages/db", results);
client.release();
} catch (err) {
console.error(err);
res.send("Error " + err);
}
})
.get("/cool", (req, res) => res.send(cool()))
.get("/times", (req, res) => res.send(showTimes()))
.listen(PORT, () => console.log(`Listening on ${PORT}`));
const showTimes = () => {
let result = "";
const times = process.env.TIMES || 5;
for (i = 0; i < times; i++) {
console.log(i);
result += i + " ";
}
return result;
};
result form method #1
Method #2
Exactly the same code from Method #1 except I take the following steps prior to running:
Kill and reopen terminal at file location (/node-js-getting-started)> Using the credentials information (User, Password, Host, Port, and Database) in the heroku datastore resources tab I run the following in order:
% export DATABASE_URL=postgres://User:Password#Host:Port/Database
% heroku local web <--This runs app # localhost:5000
results from method #2
My question is, why does the one connect and the other doesn’t?
So not sure why, but my nodeJS / NextJS app keeps triggering plesks ip_ban. I recoded our site and moved it away from ReactJS to NextJS. But seems by doing so their must be a command that is making it look like an IP address is trying to connect to many times which makes the plesk server add the IP to a ban list (the rule that keeps getting triggered is - recidive).
I am wondering what is the correct way to solve this issue. Disabling ip_ban is a temp solution but not the ideal solution.
my server.js script is very clear and has no issues (once ip_ban is disabled).
const { createServer } = require("http");
const { parse } = require("url");
const next = require("next");
const dev = process.env.NODE_ENV !== "production";
const port = !dev ? process.env.PORT : 3000;
// Create the Express-Next App
const app = next({ dev });
const handle = app.getRequestHandler();
app
.prepare()
.then(() => {
createServer((req, res) => {
const parsedUrl = parse(req.url, true);
const { pathname, query } = parsedUrl;
handle(req, res, parsedUrl);
console.log("pathname", pathname);
}).listen(port, (err) => {
if (err) throw err;
console.log(`> Ready on http://example.com:${port}`);
});
})
.catch((ex) => {
console.error(ex.stack);
process.exit(1);
});
The rule that keeps getting triggered:
[recidive]
enabled = true
filter = recidive
action = iptables-allports[name=recidive]
logpath = /var/log/fail2ban.log
maxretry = 3
I am working through the course "Build a Blockchain and Cryptocurrency From Scratch from Udemy. I have no prior experience with NodeJS I have been following along with the instructor's code, but recently hit a snag that I cannot resolve. When trying to build the project to run test scripts via npm run dev, I get the following error:
/home/OnlyDean/Workspace/udemy_blockchain_course_1/app/index.js:13
const p2pServer = new P2pServer(bc);
^
TypeError: P2pServer is not a constructor
Answers I've found online seem to indicate that I'm calling an instance of the class P2pServer rather than the constructor of the class itself. This is borne out by the output of console.log(P2pServer);, which returns [Object object]. I have scoured the code for errors, and compared my code to what the instructor has on the screen. I can't seem to find any differences. Below are my index.js and p2p-server.js classes, which I think are the only relevant files.
index.js
const express = require('express');
const bodyParser = require('body-parser');
const Blockchain = require('../blockchain');
const P2pServer = require('./p2p-server');
const HTTP_PORT = process.env.HTTP_PORT || 3001;
const app = express();
const bc = new Blockchain();
//console.log(`Blockchain = ${Blockchain}`)
console.log(`P2pServer = ${P2pServer}`)
console.log(bc)
const p2pServer = new P2pServer(bc);
app.use(bodyParser.json());
app.get('/blocks', (req, res) => {
res.json(bc.chain);
})
app.post('/mine', (req, res) => {
const block = bc.addBlock(req.body.data);
console.log(`New block added: ${block.toString()}`);
res.redirect('/blocks');
});
app.listen(HTTP_PORT, () => console.log(`Listening on port ${HTTP_PORT}`));
p2pServer.listen();
p2p-server.js
const Websocket = require('ws');
const P2P_PORT = process.env.P2P_PORT || 5001;
const peers = process.env.PEERS ? process.env.PEERS.split(',') : [];
class P2pServer {
constructor(blockchain) {
this.blockchain = blockchain;
this.sockets = [];
}
listen() {
const server = new Websocket.Server({ port: P2P_PORT});
server.on('connection', socket => this.connectSocket(socket));
this.connectToPeers();
console.log(`Listening for peer-to-peer connections on: ${P2P_PORT}`);
}
connectToPeers() {
peers.forEach(peer => {
const socket = new Websocket(peer);
socket.on('open', () => this.connectSocket(socket));
});
}
connectSocket(socket) {
this.sockets.push(socket);
console.log(`Socket connected`);
}
}
module.export = P2pServer;
Any help resolving this error would be greatly appreciated -- I'm kind of stuck with the course until I can resolve this. Thanks!
The problem is at the export of the P2pServer class
should be like this (exports and not export):
module.exports = P2pServer;
I was familiar with MongodB for CRUD operation. Here, I'm trying to make simple post request on mongodB atlas but I want to know where I have done error for the connection and posting data to MongodB atlas.
Model.js
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
let quizSchema = new Schema({
title: {
type: String,
},
description: {
type: Number,
},
question: {
type: String,
},
});
const Quiz = mongoose.model("Quiz", quizSchema);
module.exports = Quiz;
index.js
I'm trying to create the database collection name "QuizDatabase" and insert the data to it.
var express = require("express");
var bodyParser = require("body-parser");
const Quiz = require("./views/model/model");
var Request = require("request");
var app = express();
app.use(bodyParser.json());
const MongoClient = require("mongodb").MongoClient;
const uri =
"mongodb+srv://username:password#cluster0.iom1t.mongodb.net/QuizDatabase?retryWrites=true&w=majority";
const client = new MongoClient(uri, {
useNewUrlParser: true,
useUnifiedTopology: true,
});
mongoose.connect(uri);
var server = app.listen(process.env.PORT || 8080, function () {
var port = server.address().port;
console.log("App now running on port", port);
});
app.post("/new/", function (req, res) {
Quiz.collection("QuizDatabase").insertMany(req.body, function (err, doc) {
if (err) {
handleError(res, err.message, "Failed to create new quiz.");
} else {
res.status(201).send(JSON.stringify(body));
}
});
});
function handleError(res, reason, message, code) {
console.log("ERROR: " + reason);
res.status(code || 500).json({ error: message });
}
You dont have to use mongo client if you are already using mongoose.
In index.js file just import the model
const Quiz = require("./model");
And you are already using mongoose to connect to db when you write mongoose.connect(uri); You don't have to use client.connect() again.
Query to insert -
Quiz.insertMany(req.body);
Your index file should look like this -
const Quiz = require("./views/model/model");
var Request = require("request");
var app = express();
app.use(bodyParser.json());
const uri =
"mongodb+srv://username:password#cluster0.iom1t.mongodb.net/QuizDatabase?retryWrites=true&w=majority";
mongoose.connect(uri);
var server = app.listen(process.env.PORT || 8080, function () {
var port = server.address().port;
console.log("App now running on port", port);
});
app.post("/new/", function (req, res) {
Quiz.insertMany(req.body, function (err, doc) {
if (err) {
handleError(res, err.message, "Failed to create new quiz.");
} else {
res.status(201).send(JSON.stringify(body));
}
});
});
function handleError(res, reason, message, code) {
console.log("ERROR: " + reason);
res.status(code || 500).json({ error: message });
}
There are several reasons.
Connection Issues to the MongoDB database.
To check this insert app.listen() into mongoose connect. This would make sure you can only run development on your preferred PORT only when it has successfully connected to your Database. e.g From your code
mongoose.connect(uri)
.then(() => {
//listen for PORT request
var server = app.listen(process.env.PORT || 8080, function () {
var port = server.address().port;
console.log("App now running on port", port);
});
}).catch((error) => {
console.log(error);
});
Try purposely using the wrong Username or Password and see if you get this error:
MongoServerError: bad auth : Authentication failed.
at Connection.onMessage (/Users/user/Documents/..<pathway>../connection.js:207:30)
*
*
*
*
ok: 0,
code: 8000,
codeName: 'AtlasError',
[Symbol(errorLabels)]: Set(1) { 'HandshakeError' } }
If you don't get this error then you have a connection problem. To solve this, I added my current IP ADDRESS and 0.0.0.0/0 (includes your current IP address) at the Network Access page. So you click on MY CURRENT IP ADDRESS and confirm upon setting up the network. Go to NETWORK ACCESS, click on add new IP ADDRESS, input 0.0.0.0/0 and confirm. Then try using the wrong username or password in the URI link given to you to see if it gives the above-expected error, then you can now correct the Username and Password, and npm run dev or npm start (However you configured it in your package.json file).
Code issues
First of I would correct your Model.js file from this:
const Quiz = mongoose.model("Quiz", quizSchema);
module.exports = Quiz;
to this:
module.exports = mongoose.model("Quiz", quizSchema);
I can see why yours can work, but it may be an issue as you want to get the schema upon accessing the whole file.
Secondly, I would correct the code for Posting and you can do that in 2 ways using the asynchronous method. Which depends on the method of assigning the req.body.
Way 1:
app.post("/new/", async (req, res) => {
const { title, description, question } = req.body;
//adds doc to db
try {
const quiz = await Quiz.create({ title, description, question });
res.status(200).json(quiz);
} catch (error) {
res.status(400).json({ error: error.message });
}
});
OR
Way2:
app.post("/new/", async (req, res) => {
const quiz = new Quiz(req.body);
//adds doc to db
try {
const savePost = await quiz.save();
response.status(200).send(savePost);
} catch (error) {
response.status(400).send(error);
}
});
NOTE: You don't necessarily have to create a named database and collection in Mongo Atlas before starting the project. The URI given to you covers that if there are no problems with the connection to the DB or the Code.
based on your code
URI:
"mongodb+srv://username:password#cluster0.iom1t.mongodb.net/QuizDatabase?retryWrites=true&w=majority";
would create a database called: QuizDatabase and collection called: quizs (MongoDb always creates the plural word from the model given and makes it start with lowercase (i.e from your Model.js, the mongoose.model("Quiz"))).
If no database is named in your URI, then a database called test is automatically created for you as a default database, with the collection name being the mongoose.model("") given.
CONCLUSION
This should solve at least 90% of your issues, any other creation/POST problems is currently beyond my current expertise. Happy Coding 🚀🚀🚀
I have an Express application that looks like this.
const app = express();
...
...
...
router.post(...);
router.get(...);
router.delete(...);
app.use('/api/v1', router);
MongoClient.connect(mongoUri, { useNewUrlParser: true })
.then(client => {
const db = client.db('db_name');
const collection = db.collection('collection_name');
app.locals.collection = collection;
})
.catch(error => console.error(error));
const server = app.listen(settings.APIServerPort, () => console.log(`Server is listening on port ${settings.APIServerPort}.`));
module.exports = {
server,
knex // using this to connect to the RDBMS
}
The application uses both an RDBMS and Mongo.
I wrote tests for the application using Mocha and added the following block to the Mocha test.
const app = require('../app');
...test 1...
...test 2...
...test 3...
...
...
...
...test n...
after(async () => {
await app.knex.destroy();
});
The after hook closes out my connection to the RDBMS.
However, I don't know how to close the MongoDB connection once the test finishes.
Owing to keeping this connection open, the test never exits and hangs once all the tests have been run.
The closest answer that I have been able to find is this one - Keep MongoDB connection open while running tests using mocha framework.
However, I was unable to get to work for me.
Can someone please help with this?
Update
A combination of the answers below is what solved the problem.
const mongoClient = new MongoClient(mongoUri, { useNewUrlParser: true });
mongoClient.connect()
.then(client => {
const db = client.db('...');
const collection = db.collection('...');
app.locals.collection = collection;
})
.catch(error => console.error(error));
const server = app.listen(settings.APIServerPort, () => console.log(`Server is listening on port ${settings.APIServerPort}.`));
module.exports = {
server,
knex,
mongoClient
}
We can rewrite the mongo function to make it work
const client = new MongoClient(uri);
client.connect()
.then(client => {
const db = client.db('db_name');
const collection = db.collection('collection_name');
app.locals.collection = collection;
})
.catch(error => console.error(error));
And in the after block -
after(async () => {
await app.knex.destroy();
await client.close();
});