Unhandled Rejection (Error): Request failed with status code 404 - node.js

I'm trying to learn MERN/CRUD but running into an issue when I attempt to POST to my database. Trying to reach it via Insomniac gives me a 'cannot POST /users' error, and the console gives me a 'Unhandled Rejection (Error): Request failed with status code 404' error.
app.js
let express = require('express'),
mongoose = require('mongoose'),
dbConfig = require('./database/db'),
cors = require('cors');
const userRoute = require('./routes/user.route');
mongoose.Promise = global.Promise;
mongoose.connect(dbConfig.db, {
useNewUrlParser: true,
useUnifiedTopology: true
}).then(() => {
console.log('Connection established with database...') },
error => { console.log(`Error when connecting to database: ${error}`);
})
const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cors());
app.use('/users', userRoute);
const port = process.env.PORT || 4000;
const server = app.listen(port, () => {
console.log(`Successfully connected on port: ${port}`)
});
Part of create-user-component.js
onSubmit(e) {
e.preventDefault();
const userObject = {
firstName: this.state.firstName,
lastName: this.state.lastName,
email: this.state.email
};
axios.post('http://localhost:4000/users', userObject)
.then(res => console.log(res.data));
this.setState({ firstName: '', lastName: '', email: '' });
}
user.route.js
let mongoose = require('mongoose'),
express = require('express'),
router = express.Router();
let userSchema = require('../models/User');
// CREATE/POST User
router.route('/users').post((req, res, next) => {
userSchema.create(req.body, (error, data) => {
if (error) {
return next(error)
} else {
console.log(data)
res.json(data)
}
})
});
router.route('/users').get((req, res) => {
userSchema.find((error, data) => {
if (error) {
return next(error);
} else {
res.json(data);
}
})
})
router.route('/users/:id').get((req, res) => {
userSchema.findById(req.params.id, (error, data) => {
if (error) {
return next(error);
} else {
res.json(data);
}
})
})
module.exports = router;

Can you try like this ? By removing users statement from routes. Since you already defined it in app.use('/users', userRoute);, all routes defined in users.route.js will start with users by default.
let mongoose = require('mongoose'),
express = require('express'),
router = express.Router();
let userSchema = require('../models/User');
// CREATE/POST User
router.route('/').post((req, res, next) => {
userSchema.create(req.body, (error, data) => {
if (error) {
return next(error)
} else {
console.log(data)
res.json(data)
}
})
});
router.route('/').get((req, res) => {
userSchema.find((error, data) => {
if (error) {
return next(error);
} else {
res.json(data);
}
})
})
router.route('/:id').get((req, res) => {
userSchema.findById(req.params.id, (error, data) => {
if (error) {
return next(error);
} else {
res.json(data);
}
})
})

Related

Error: Unable to acquire a connection Knex postgres

I have added a model to my frontend and backend so that users can update their profile (name age etc.), however, when I'm trying to update my test user name it's not updating, and I'm recieving the below error message in my terminalTerminal error
See below my server.js and profile.js
SERVER.JS
const express = require("express");
const bodyParser = require("body-parser");
const bcrypt = require("bcrypt-nodejs");
const cors = require("cors");
const knex = require("knex");
const register = require("./controllers/register");
const signin = require("./controllers/signin");
const profile = require("./controllers/profile");
const image = require("./controllers/image");
const { Pool } = require("pg");
const morgan = require("morgan");
const nodemailer = require("nodemailer");
process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = "1";
const pool = new Pool({
connection: process.env.POSTGRES_URI,
ssl: process.env.DATABASE_URI ? true : false,
});
const db = knex({
client: "pg",
connection: process.env.POSTGRES_URI,
ssl: {
rejectUnauthorized: false,
},
});
const app = express();
app.use(bodyParser.json());
app.use(morgan("combined"));
app.use(cors());
app.get("/", (req, res) => {
res.send("it is working");
});
app.post("/signin", (req, res) => {
signin.handleSignin(req, res, db, bcrypt);
});
app.post("/register", (req, res) => {
register.handleRegister(req, res, db, bcrypt);
});
app.get("/profile/:id", (req, res) => {
profile.handleProfile(req, res, db);
});
app.post("/profile/:id", (req, res) => {
profile.handleProfileUpdate(req, res, db);
});
app.put("/image", (req, res) => {
image.handleImage(req, res, db);
});
app.post("/imageurl", (req, res) => {
image.handleApiCall(req, res);
});
app.post("/sendResetPassowrdLink", (req, res) => {
const email = req.body.email;
pool.query(`SELECT * FROM login WHERE email='${email}'`).then((data) => {
if (data.rowCount === 0) {
return res
.status(401)
.json({ message: "user with that email does not exists" });
}
const { email } = data.rows[0];
const emailBody = `your sever url is http://localhost:3001/resetpassword/${btoa(
email
)}`;
res.send(emailBody);
});
});
app.get("/resetpassword/:token", (req, res) => {
const email = atob(req.params.token);
const { newPassowrd, newPassowrdConfirm } = req.body;
if (newPassowrd !== newPassowrdConfirm) {
return res.status(400).json({ message: "passowrd does not match" });
}
const hash = bcrypt.hashSync(newPassowrd);
pool
.query(`UPDATE login SET hash='${hash}' WHERE email='${email}'`)
.then((data) => {
if (data.rowCount === 1) {
return res
.status(200)
.json({ message: "password updated successfully" });
}
});
});
const PORT = process.env.PORT || 3005;
app.listen(PORT, () => {
console.log(`app is running on port ${PORT}`);
});
PROFILE.JS
const handleProfile = (req, res, db) => {
const { id } = req.params;
db.select("*")
.from("users")
.where({ id })
.then((user) => {
if (user.length) {
res.json(user[0]);
} else {
res.status(400).json("not found");
}
})
.catch((err) => res.status(400).json("error getting user"));
};
const handleProfileUpdate = (req, res, db) => {
const { id } = req.params;
const { name, age, pet } = req.body.formInput;
db("users")
.where({ id })
.update({ name })
.then((resp) => {
if (resp) {
res.json("success");
} else {
res.status(400).json("Unable to udpate");
}
})
.catch((err) => console.log(err));
};
module.exports = {
handleProfile,
handleProfileUpdate,
};
I also recently added docker container to my backend and database, could that be the cause for the issue?
below is my github backend repo with the docker included
https://github.com/Moshe844/smartbrain-api/tree/master

how to find element by name using mongoose

I am trying to get the title of an element that's already in the database. I am using find() to get the title but when I try to print it. I get an empty array which shouldn't be the case. here is the function that I am having a problem with. Thank you so much in advance!
the function
...
posts.find({}, (err, foundPosts) => {
console.log(foundPosts[0].title);
if (foundPosts.length !== 0) {
if (err) {
console.log("Error", err);
} else {
//i still have a problem here
const postTitle = _.kebabCase(foundPosts[0].title);
const postTil = _.upperFirst(postTitle);
console.log(postTil);
if (postTil === reqTitel) {
console.log("true");
res.render("posts", { foundPosts: foundPosts[0] });
}
}
}
});
});
Here is the entire code
I am only able to get the first title because I am using index[0]
const express = require("express");
const bodyParser = require("body-parser");
const ejs = require("ejs");
const app = express();
const _ = require("lodash");
const mongoose = require("mongoose");
app.set("view engine", "ejs");
app.use(express.static(__dirname + "/public"));
app.use(bodyParser.urlencoded({extended: true}));
const items = [];
mongoose
.connect("mongodb+srv://zaid:password#cluster0.3nbpg.mongodb.net/post", {
useNewUrlParser: true,
useUnifiedTopology: true,
useUnifiedTopology: true,
})
.then(() => console.log("mongoDB connected"))
.catch((err) => console.log(err));
const postsSchema = new mongoose.Schema({title: String, content: String});
const posts = mongoose.model("post", postsSchema);
app.get("/", (req, res) => {
posts.find({}, (err, foundPosts) => {
if (foundPosts.length !== 0) {
if (err) {
console.log("error line 23", err.message);
res.render("laoding");
} else {
console.log("successful");
res.render("index", {items: foundPosts});
}
}
});
// console.log(posts.find({title}));
});
app.get("/post", (req, res) => {
res.render("post");
});
app.post("/post", (req, res) => {
const title = req.body.title;
const content = req.body.content;
const post = new posts({
title,
content,
});
post.save();
res.redirect("/");
});
app.get("/posts/:title", (req, res) => {
var requstedTilte = _.kebabCase(req.params.title);
var reqTitel = _.upperFirst(requstedTilte);
console.log(reqTitel);
posts.find({}, (err, foundPosts) => {
console.log(foundPosts[0].title);
if (foundPosts.length !== 0) {
if (err) {
console.log("Error", err);
} else {
//i still have a problem here
const postTitle = _.kebabCase(foundPosts[0].title);
const postTil = _.upperFirst(postTitle);
console.log(postTil);
if (postTil === reqTitel) {
console.log("true");
res.render("posts", {foundPosts: foundPosts[0]});
}
}
}
});
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server is listening on port ${PORT}`);
});

Error: Route.get() requires a callback function but got a [object Undefined] despite module.exports = router; being there?

I am trying to combine my CRUD and TODO application. However, I received this error even though I have added the "module.exports = router;" to my routes js files, server.js file and controller js files. I will add these files below and my folder file structure. Have I missed something?
folder/file structure
server.js file
require('./models/db');
require('./models/task');
const express = require('express');
const path = require('path');
const exphbs = require('express-handlebars');
const bodyparser = require('body-parser');
const logger = require('morgan');
const mongoose = require('mongoose');
const favicon = require('serve-favicon');
const employeeController = require('./controllers/employeeController');
var app = express();
//setting up morgan middleware
app.use(logger('dev'));
app.use(bodyparser.urlencoded({
extended: true
}));
app.use(bodyparser.json());
app.set('views', path.join(__dirname, '/views/'));
app.engine('hbs', exphbs({ extname: 'hbs', defaultLayout: 'mainLayout', layoutsDir: __dirname + '/views/layouts/' }));
app.set('view engine', 'hbs');
//serving blank favicon to keep from throwing 404 errors
app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')))
//setting up static path for serving static files
app.use(express.static(path.join(__dirname, 'public')));
//Bringing in the routes
const index = require('./routes/index');
const api = require('./routes/api');
app.use('/', index);
app.use('/api', api);
app.listen(3000, () => {
console.log('Express server started at port : 3000');
});
app.use('/employee', employeeController);
module.exports = router;
employeeController.js file
const express = require('express');
var router = express.Router();
const mongoose = require('mongoose');
const Employee = mongoose.model('Employee');
const Task = require('../models/task');
router.get('/', (req, res) => {
res.render("employee/addOrEdit", {
viewTitle: "Insert Module"
});
});
router.get('/test', (req, res) => {
res.render("employee/test");
});
router.get('/edit', (req, res) => {
res.render("edit");
});
router.get('/index', function(req, res) {
res.render('employee/index', {layout: 'main.hbs'});
});
router.get('/edit', function(req, res) {
res.render('employee/edit', {layout: 'main.hbs'});
});
router.post('/', (req, res) => {
if (req.body._id == '')
insertRecord(req, res);
else
updateRecord(req, res);
});
function insertRecord(req, res) {
var employee = new Employee();
employee.fullName = req.body.fullName;
employee.module = req.body.module;
employee.mobile = req.body.mobile;
employee.city = req.body.city;
employee.save((err, doc) => {
if (!err)
res.redirect('employee/list');
else {
if (err.name == 'ValidationError') {
handleValidationError(err, req.body);
res.render("employee/addOrEdit", {
viewTitle: "Insert Module",
employee: req.body
});
}
else
console.log('Error during record insertion : ' + err);
}
});
}
function updateRecord(req, res) {
Employee.findOneAndUpdate({ _id: req.body._id }, req.body, { new: true }, (err, doc) => {
if (!err) { res.redirect('employee/list'); }
else {
if (err.name == 'ValidationError') {
handleValidationError(err, req.body);
res.render("employee/addOrEdit", {
viewTitle: 'Update Module',
employee: req.body
});
}
else
console.log('Error during record update : ' + err);
}
});
}
router.get('/list', (req, res) => {
Employee.find((err, docs) => {
if (!err) {
res.render("employee/list", {
list: docs
});
}
else {
console.log('Error in retrieving module list :' + err);
}
});
});
function handleValidationError(err, body) {
for (field in err.errors) {
switch (err.errors[field].path) {
case 'fullName':
body['fullNameError'] = err.errors[field].message;
break;
case 'module':
body['moduleError'] = err.errors[field].message;
break;
default:
break;
}
}
}
router.get('/:id', (req, res) => {
Employee.findById(req.params.id, (err, doc) => {
if (!err) {
res.render("employee/addOrEdit", {
viewTitle: "Update Module",
employee: doc
});
}
});
});
router.get('/delete/:id', (req, res) => {
Employee.findByIdAndRemove(req.params.id, (err, doc) => {
if (!err) {
res.redirect('/employee/list');
}
else { console.log('Error in module delete :' + err); }
});
});
const sortTask = (a,b) => {
const taskA = a.task.toLowerCase();
const taskB = b.task.toLowerCase();
return (taskA < taskB) ? -1 : (taskA > taskB) ? 1 : 0;
}
module.exports = {
findAll: function (req,res){
Task
.find({})
.then(result => {
result.sort(sortTask)
res.render('employee/index', {layout: 'main.hbs'}, {tasks: result})
})
.catch(err => res.json(err))
},
create: function(req,res){
Task
.create(req.body)
.then(result => {
// result.sort(sortTask)
res.json(result)
})
.catch(err => res.json(err));
},
findOne: function (req,res){
Task
.findOne({_id: req.params.id})
.then(result => res.render('employee/edit', {layout: 'main.hbs'}, result))
.catch(err => res.json(err))
},
complete: function (req,res){
Task
.findOneAndUpdate({_id: req.params.id}, {completed: true})
.then(result => res.json(result))
.catch(err => res.json(err))
},
deleteOne: function (req,res){
Task
.remove({_id: req.params.id})
.then(result => res.json(result))
.catch(err => res.json(err))
},
updateName: function (req,res){
Task
.findOneAndUpdate({_id: req.body._id}, {task: req.body.task})
.then(result => res.json(result))
.catch(err => res.json(err))
}
}
module.exports = router;
api.js file
const router = require('express').Router();
const taskController = require('../controllers/employeeController');
router
.route('/task/:id')
.get(taskController.findOne)
.put(taskController.complete)
.delete(taskController.deleteOne)
router.post('/create', taskController.create);
router.post('/update', taskController.updateName);
module.exports = router;
index.js file
const router = require('express').Router();
const taskController = require('../controllers/employeeController');
router.get('/', taskController.findAll)
module.exports = router;
You are using module.exports = {...} multiple times in employeeController.js and this is not how it works, please see the docs to learn more
To fix this just add the router to the first exported object like this:
module.exports = {
findAll: function (req,res) {
...
},
// rest of the functions
updateName: function(req,res) {
...
},
router
}
̶m̶o̶d̶u̶l̶e̶.̶e̶x̶p̶o̶r̶t̶s̶ ̶=̶ ̶r̶o̶u̶t̶e̶r̶;̶
And then in server.js use the router like this:
app.use('/employee', employeeController.router);

Heroku - Request timed out for fetching request

On localhost:5000/posts my data is successfully showing but if I do the same thing in Heroku: https://rest-in-peep.herokuapp.com/posts I get an application error. https://rest-in-peep.herokuapp.com/ works fine and I deployed it through Heroku GIT. I made sure to config my environmental vars in Heroku and added a Procfile but I am still getting this application error. I've been trying all day to figure this out but what I expect to happen is if I type in https://rest-in-peep.herokuapp.com/posts, I will get all the data that is being stored on my MongoDB database.
app.js file
const http = require("http");
const express = require("express");
const mongoose = require("mongoose");
const bodyParser = require("body-parser");
const cors = require("cors");
require("dotenv/config");
const app = express();
const server = http.createServer(app);
//Middlewares
app.use(cors());
app.use(bodyParser.json());
//Import Routes
const postsRoute = require("./routes/posts");
app.use("/posts", postsRoute);
//ROUTES
app.get("/", (req, res) => {
res.send("We are on home");
});
//Connect to DB
mongoose.connect(
process.env.DB_CONNECTION,
{ useNewUrlParser: true },
() => console.log("connected to MongoDB")
);
//How do we start listening to the server
server.listen(process.env.PORT || 5000, () => {
console.log("App now running on PORT");
});
routes>
posts.js
const express = require("express");
const Post = require("../models/Posts");
const router = express.Router();
//GETS BACK ALL THE POSTS
router.get("/", async (req, res) => {
try {
const posts = await Post.find();
res.json(posts);
} catch (err) {
res.json({ message: err });
}
});
//SUBMITS A POST
router.post("/", async (req, res) => {
console.log(req);
const post = new Post({
quote: req.body.quote
});
try {
const savedPost = await post.save();
res.json(savedPost);
} catch (err) {
res.json({ message: err });
}
});
//SPECIFIC POST
router.get("/:postId", async (req, res) => {
try {
const post = await Post.findById(req.params.postId);
res.json(post);
} catch (err) {
res.json({ message: err });
}
});
//Delete Post
router.delete("/:postId", async (req, res) => {
try {
const removedPost = await Post.remove({ _id: req.params.postId });
res.json(removedPost);
} catch (err) {
res.json({ message: err });
}
});
//Update a post
router.patch("/:postId", async (req, res) => {
try {
const updatedPost = await Post.updateOne(
{ _id: req.params.postId },
{
$set: { quote: req.body.quote }
}
);
res.json(updatedPost);
} catch (err) {
res.json({ message: err });
}
});
module.exports = router;
gitignore
/node_modules
models>Posts.js
const mongoose = require("mongoose");
const PostSchema = mongoose.Schema({
quote: {
type: String,
required: true
}
});
module.exports = mongoose.model("Posts", PostSchema);

MongoDB and Cosmos DB key error collection

I'm trying to create my first MongoDB app with Express & Angular & Azure Cosmos DB.
Here is my js files:
hero.model.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const heroSchema = new Schema({
id: {
type: Number,
required: true,
unique: true
},
name: String
}, {
collection: 'Heroes'
})
const Hero = mongoose.model('Hero', heroSchema);
module.exports = Hero;
mongo.js
const mongoose = require('mongoose');
mongoose.Promise = global.Promise;
const env = require('./env/environment');
const mongoUri =
mongodb:`${env.accountName}:${env.key}#${env.accountName}
.documents.azure.com:10255/?ssl=true`
function connect() {
mongoose.set('debug', true);
return mongoose.connect(mongoUri)
}
module.exports = {
connect,
mongoose
};
index.js
const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');
const routes = require('./routes');
const root = './';
const port = process.env.PORT || '3000';
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(path.join(root, 'docs')));
app.use('/api', routes);
app.get('*', (req, res) => {
res.sendFile('docs/index.html', {root});
});
route.js
const express = require('express');
const router = express.Router();
const heroService = require('./hero.service');
router.get('/heroes', (req, res) => {
heroService.getHeroes(req, res);
});
router.post('/hero', (req, res) => {
heroService.postHero(req, res);
});
router.put('/hero/:id', (req, res) => {
heroService.putHero(req, res);
});
router.delete('/hero/:id', (req, res) => {
heroService.deleteHero(req, res);
});
module.exports = router;
app.listen(port, () => console.log(`API running on
localhost:${port}`));
hero.service.js
const Hero = require('./hero.model');
require('./mongo').connect();
function getHeroes(req, res) {
const docquery = Hero.find({});
docquery
.exec()
.then(heroes => {
res.status(200).json(heroes);
})
.catch(error => {
res.status(500).send(error);
return;
});
}
function postHero(req, res) {
const originalHero = {
id: req.body.id,
name: req.body.name
};
const hero = new Hero(originalHero);
hero.save(error => {
if (checkServerError(res, error)) return;
res.status(201).json(hero);
console.log('Hero created successfully!');
});
}
function checkServerError(res, error) {
if (error) {
res.status(500).send(error);
return error;
}
}
function putHero(req, res) {
const originalHero = {
id: parseInt(req.params.id, 10),
name: req.body.name
};
Hero.findOne({
id: originalHero.id
}, (error, hero) => {
if (checkServerError(res, error)) return;
if (!checkFound(res, hero)) return;
hero.name = originalHero.name;
hero.save(error => {
if (checkServerError(res, error)) return;
res.status(200).json(hero);
console.log('Hero updated successfully!');
});
});
}
function deleteHero(req, res) {
const id = parseInt(req.params.id, 10);
Hero.findOneAndRemove({
id: id
})
.then(hero => {
if (!checkFound(res, hero)) return;
res.status(200).json(hero);
console.log('Hero deleted successfully!');
})
.catch(error => {
if (checkServerError(res, error)) return;
});
}
function checkFound(res, hero) {
if (!hero) {
res.status(404).send('Hero not found.');
return;
}
return hero;
}
module.exports = {
getHeroes,
postHero,
putHero,
deleteHero
};
It only works when I POST a new hero for the first time and a second time gives me an error:
E11000 duplicate key error collection: admin.Heroes Failed _id or unique key constraint.
Please help!!
Thanks.
I know it's been a while but I've encountered the same problem. The solution is avoid using the field name id, rename it to UID or something. Once you done that you have to remove the entire collection and restart.
If you are following the Microsoft CosmosDB Angular tutorial, you can clone the repo below and test it on your local.
https://github.com/Azure-Samples/angular-cosmosdb
If you are using a newer version of mongoose you have to upgrade the connection string below.
//useMongoClient: true
useNewUrlParser: true

Resources