I'm new in Express.js,MongoDb and mongoose, I have created HTTP request methods, but when running the Post method, nothing done (nothing saved in the database), and postman continues loading and it stops only when I cancel.
I want to know what's wrong in my code, thank you .
this is my routes file 'department.js':
const express = require("express");
const router = express.Router();
const Department = require("../models/department")
router.get("/v1/departments", async (req, res) => {
try {
const departments = await Department.find({ isDeleted: false })
if (!departments) {
return res.status(404).send()
}
res.status(200).send()
} catch (error) {
res.status(500).send(error)
}
});
router.get("/v1/department/:id", async (req, res) => {
//test if the department exist => by id
const _id = req.params._id
try {
const depatment = await Department.findByid(_id, { isDeleted: false })
if (!depatment) {
return res.status(404).send()
}
res.status(200).send(depatment)
} catch (error) {
res.status(500).send(error)
}
});
router.post("/department", async (req, res) => {
const department = new Department(req.body) //this param is for testing the post methode by sending request from postman
try {
await department.save()
// res.status(201).send(department)
} catch (error) {
res.status(500).send(error)
}
});
router.put("/v1/department/:id", async (req, res) => {
//updates , allowedUpdates ,isValideOperations : those constants are used for checking if the updated fields exists or not !
//especially useful when testing the put method using postman
const updates = Object.keys(req.body)
const allowedUpdates = ['name', 'email']
const isValideOperations = updates.every((update) => allowedUpdates.includes(update)) //isValideOperations return true if all keys exists
if (!isValideOperations) {
return res.status(400).send({ error: 'Invalid updates' })
}
try {
const _id = req.params.id
const department = await Department.findByIdAndUpdate(_id)
if (!department) {
return res.status(404).send()
}
res.send(department)
} catch (error) {
res.status(500).send(error)
}
})
//Safe delete by updating the field isDeleted to true
router.delete('/v1/department/:id', async (req, res) => {
try {
const _id = req.params.id
const department = await Department.findByIdAndUpdate(_id, { isDeleted: true })
if (!department) {
return res.status(400).send()
}
res.status(200).send(department)
} catch (error) {
res.status(500).send(error)
}
})
module.exports = router
And this is the Model
const mongoose = require("mongoose");
const validator = require('validator')
const Department = mongoose.model('Department', {
name: {
type: String,
required: true,
}
,
email: {
type: String,
required: true,
trim: true,
lowercase: true,
validate(value) {
if (!validator.isEmail(value)) {
throw new Error('Invalid email!')
}
}
}
,
createdBy: {
type: String,
default: 'SYS_ADMIN'
}
,
updatedBy: {
type: String,
default: 'SYS_ADMIN'
}
,
createdAt: {
type: Date
// ,
// default: Date.getDate()
}
,
updatedAt: {
type: Date
// ,
// default: Date.getDate()
},
isDeleted: {
type: Boolean,
default: false
}
})
module.exports = Department
this is Index.js (the main file)
const express = require("express");
const app = express()
const departmentRouter = require("../src/routes/department")
app.use(express.json())
app.use(departmentRouter)
//app.use('/', require('./routes/department'))
const port = process.env.PORT || 3000;//local machine port 3000
app.listen(port, () => (`Server running on local machine port ${port} 🔥`));
In order for you to get a response in Postman (or in an API call in general), you must actually send back a response, whether it's with sendFile, render, json, send, etc. These methods all call the built-in res.end which sends back data. However you commented out res.send which is the reason
I think you forget to add '/v1' in this route. it should be
router.post("/v1/department", async (req, res) => {
const department = new Department(req.body) //this param is for testing the post methode by sending request from postman
try {
await department.save()
// res.status(201).send(department)
} catch (error) {
res.status(500).send(error)
}
});
Related
I've read through some of the answers similar to this question and have struggled to see how they would apply to mine. The issue I am having is that when I try to retrieve any data from my MongoDB database, it returns an empty array. I've already set my network access to 0.0.0.0/0, and it says it successfully connects to my DB when I run my backend. I was hoping someone might be able to lend a hand. The GitHub for this file is https://github.com/dessygil/des-personal-site-backend
Here is my index.js file
const express = require("express");
const app = express();
const dotenv = require('dotenv').config();
const mongoose = require("mongoose")
const jobsRoute = require("./routes/jobs");
mongoose.set('strictQuery', false);
app.use(express.json());
mongoose.connect(process.env.MONGO_URL, {
useNewUrlParser: true,
useUnifiedTopology: true,
}).then(console.log("Connected to MongoDB")).catch((err) => {
console.log(err)
});
app.use("/", jobsRoute);
app.listen(process.env.PORT || 5000, () => {
console.log("Connected to port 5000");
});
My Jobs model
const mongoose = require("mongoose");
const JobSchema = new mongoose.Schema(
{
startDate: {
type: Date,
required: true,
},
endDate: {
type: Date,
required: false,
},
company: {
type: String,
required: true,
unique: false,
},
title: {
type: String,
required: true,
unique: true,
},
url: {
type: String,
required: true,
},
duties: {
type: [String],
required: true,
},
},
{ timestamps: true },
);
module.exports = mongoose.model("Job", JobSchema)
My route file
const router = require("express").Router();
const Job = require("../models/Job");
//Create new post
router.post("/", async (req, res) => {
const newJob = new Job(req.body);
try {
const savedJob = await newJob.save();
res.status(200).json(savedJob);
} catch (err) {
res.status(500).json(err);
};
});
//Update post
router.put("/:id", async (req, res) => {
try {
const updatedJob = await Job.findByIdAndUpdate(
req.params.id,
{
$set: req.body,
},
{ new: true }
);
res.status(200).json(updatedJob);
} catch (err) {
res.status(500).json(err);
}
});
//Delete post
router.delete("/:id", async (req, res) => {
try {
const job = await Job.findById(req.params.id);
await job.delete()
res.status(200).json("Post had been deleted");
} catch (err) {
res.status(500).json(err);
}
});
//Get post
router.get("/:id", async (req, res) => {
try {
const job = await Job.findById(req.params.id);
res.status(200).json(job);
} catch (err) {
res.status(500).json(err);
}
});
//Get all posts
router.get("/", async (req, res) => {
try {
allJobs = await Job.find();
console.log(allJobs,"you are here");
res.status(200).json(allJobs);
} catch (err) {
res.status(500).json(err);
}
});
module.exports = router;
The structure of my db
What is returned on postman (hosted on heroku but also doesn't work when I run locally and returns the same results
The type of data stored in jobs there is 3 documents that should show up
I am creating a MERN stack based website, and was able to write GET and POST requests for two out of the three models I have created so far: users and profile. The latest one, tests, is giving an error of Cannot POST /api/tests. Here's the code:
server.js
const connectDB = require('./config/db');
const app = express();
//Connecting DB
connectDB()
app.use(express.json({extended: false}));
app.get('/',(req,res)=>res.send('API Running'));
app.use('/api/users',require('./routes/api/users'));
app.use('/api/auth',require('./routes/api/auth'));
app.use('/api/profile',require('./routes/api/profile'));
app.use('/api/tests', require('./routes/api/tests'));
const PORT = process.env.Port || 5000;
app.listen(PORT, ()=> console.log(`Server started on port on ${PORT}`));
Test.js
const TestSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
domain: {
type: String,
required: true
},
activeStatus: {
type: Boolean,
required: true
},
questions: [
{
question: {
type: String,
required: true
},
option1: {
type: String,
required: true
},
option2: {
type: String,
required: true
},
option3: {
type: String,
required: true
},
option4: {
type: String,
required: true
},
answer: {
type: Number,
required: false
}
}
]
});
module.exports = Test = mongoose.model('test', TestSchema);
tests.js
const router = express.Router();
const { check, validateResult } = require('express-validator/check');
const auth = require('../../middleware/Auth');
const Test = require('../../models/Test');
const User = require('../../models/User');
// #route POST api/tests
// #desc Create or Update a test
// #access Private
router.post('/', [
check('name', 'Name is required').not().isEmpty(),
check('domain', 'Domain is required').not().isEmpty(),
check('status', 'Status is required').not().isEmpty()
],
async (req, res) => {
console.log("entered");
const errors = validationResult(req);
if(!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
const {
name,
domain,
status
} = req.body;
//build test object
const testFields = {};
if(name) testFields.name = name;
if(domain) {console.log(123); testFields.domain = domain;}
if(status) testFields.status = status;
testFields.questions = {};
try {
//see if test exists
// let test = await Test.findOne({name});
// if(test){
// return res.status(400).json({ errors: [{msg: "Test already exists"}] });
// }
//create
test = new Test(testFields);
await test.save();
res.json(test);
console.log(testFields);
res.send('Test Created')
} catch (err) {
console.error(err.message);
res.status(500).send('Server Error');
}
});
// #route GET api/tests
// #desc Get particular test
// #access Private
router.get('/', auth, async (req, res) => {
try {
const test = await Profile.findById(req.test.id);
console.log(test);
if(!test)
return res.status(400).json({ msg: 'Test not found' });
res.json(test);
} catch (err) {
console.error(err.message);
res.status(500).send('Server Error');
}
});
module.exports = router;
Things I've already tried:
Checked and rechecked the URL entered in Postman (http://localhost:5000/api/tests)
Set the URL type in Postman to POST
Made sure the URL was properly registered, and compared with working URLs and files
Even after this, nothing has worked so far. I am fairly new to this, so that might be the cause of my oversight, please do let me know if you can spot where it's going wrong.
I know there is a lot of post about that but none have my problem, my tables exist, the path work to some extent but two of the request just return null and I have no idea why.
Here the request that dont work :
// *Get Chat Message*
router.get("/message/:MessageId",async(req, res)=>{
try{
const message = await Message.findById(req.params.MessageId);
res.status(200).json(message)
} catch (err){
res.status(500).json(err)
}
})
// *Get All Chat Message*
router.get("/message/findAll",async(req, res)=>{
try {
const messages = await Message.find();
res.status(200).json(messages)
} catch (err) {
res.status(500).json(err);
}
})
If need here is the rest of the file where ALL the requests work PERFECTLY so I don't know why only those two don't work.
const router = require("express").Router();
const Post = require("../models/Post");
const User = require("../models/User");
const Chat = require("../models/Chat");
const Message = require("../models/ChatMessage");
// * Get a Chat *
router.get("/:firstUserId/:secondUserId", async(req, res) => {
const chat = await Chat.findOne({ users: { $all: [req.params.firstUserId, req.params.secondUserId] } });
res.status(200).json(chat);
})
// * Get every Chat of one user *
router.get("/:userId", async(req, res) => {
try{
const chats = await Chat.find({ users: { $all: [req.params.userId]} });
res.status(200).json(chats);
}catch(err){
res.status(500).json(err);
}
})
// *Create Chat*
router.post("/",async(req, res)=>{
const chat = new Chat(req.body)
try {
const savedChat = await chat.save();
res.status(200).json(savedChat);
}catch(err){
res.status(500).json(err)
}
})
// *Delete Chat*
router.delete("/:firstUserId/:secondUserId",async(req, res)=>{
const chat = await Chat.findOne({ users: { $all: [req.params.firstUserId, req.params.secondUserId] } });
try{
chat.deleteOne();
res.status(200).json("The chat has been delete successfully.")
} catch (err){
res.status(500).json(err)
}
})
// *Put Chat Message*
router.put("/message",async(req, res)=>{
const newMessage = new Message(req.body)
try {
const savedMessage = await newMessage.save();
res.status(200).json(savedMessage)
} catch (err) {
res.status(500).json(err)
}
})
The schema name and parameter of the database are the same so I don't know why it doesn't work. It still returns null even if I erase the two that don't work, it only returns an error if I delete the whole file.
Here is my schema:
const mongoose = require("mongoose");
const ChatMessageSchema = new mongoose.Schema({
conversationId: {
type: String,
required: true
},
userId: {
type: String,
required: true
},
content: {
type: String,
required: true,
max: 5000
},
state: {
type: Number,
default: 0
}
},
{ timestamps: true }
);
module.exports = mongoose.model("chat_message", ChatMessageSchema,"chat_messages");
The table
Request done in Postman
to get all document use
Model.find({});
and for single try the following
Model.findOne({_id: <id>})
Finaly found the error.
The problem is that for express /message and /message/:MessageId were on the same path.
/findAll still does not work but I don't need it.
I have a middleware that uses express-validator to validate request,
const { validationResult } = require("express-validator");
module.exports = {
validate: (req, res, next) => {
const raw_errors = validationResult(req);
if (raw_errors.isEmpty()) {
return next()
}
const errors = raw_errors.errors.map((err) => ({ message: err.msg }));
return res.status(422).json({ status: "error", errors });
},
}
I use it on the route like so:
const { validate } = require('../middlewares/validation')
routes.post('/', validate, (req, res) => {
postService.add(req.body.name, req.body.description).then(post => {
res.status(201).json({ message: 'post added', data: post })
}).catch(error => {
handleError(error, res)
})
})
But when i try to make an API call with an empty request body, it does not return any errors.
Here is my model
const mongoose = require('mongoose');
const PostSchema = mongoose.Schema( {
name: {
type: String,
required: [true, 'Please provide a name'],
},
description: {
type: String,
required: [true, 'Please provide a description'],
}
},
{timestamps: true}
);
module.exports = mongoose.model('Post', PostSchema);
Here is my postService
module.exports = {
//adds a post
add : async (name, description) => {
try{
const tab = { name, description }
return postModel.create(tab)
}
catch(err){
throw new ErrorHandler(500, "Unable to add post at this time. Please try again later.")
}
},
}
When I log raw_errors from the middleware, I get - Result { formatter: [Function: formatter], errors: [] }
Please what might be wrong?
I'm new to NodeJS,I'm just trying to create a restfull API, but when I try to execute the code by running (npm run dev),it's throwing an error.There are many questions like this one, but no answer could figure out what is wrong in my code.
the error is : app.use() requires a middleware function
this is my index.js
const express = require("express");
const app = express()
const departmentRouter = require("../src/routes/department")
app.use(express.json())
app.use(departmentRouter)
const port = process.env.PORT || 3000;//local machine port 3000
app.listen(port, () => (`Server running on local machine port ${port} 🔥`));
this is the model :
const mongoose = require("mongoose");
const validator = require('validator')
const Department = mongoose.model('Department', {
name: {
type: String,
required: true,
}
,
email: {
type: String,
required: true,
trim: true,
lowercase: true,
validate(value) {
if (!validator.isEmail(value)) {
throw new Error('Invalid email!')
}
}
}
,
createdBy: {
type: String,
default: 'SYS_ADMIN'
}
,
updatedBy: {
type: String,
default: 'SYS_ADMIN'
}
,
createdAt: {
type: Date
// ,
// default: Date.getDate()
}
,
updatedAt: {
type: Date
// ,
// default: Date.getDate()
},
isDeleted: {
type: Boolean,
default: false
}
})
module.exports = Department
this is routes file (department.js)
const express = require("express");
const router = express.Router();
const Department = require("../models/department")
router.get("/v1/departments", async (req, res) => {
try {
const departments = await Department.find({ isDeleted: false })
if (!departments) {
return res.status(404).send()
}
res.status(200).send()
} catch (error) {
res.status(500).send(error)
}
});
router.get("/v1/department/:id", async (req, res) => {
//test if the department exist => by id
const _id = req.params._id
try {
const depatment = await Department.findByid(_id, { isDeleted: false })
if (!depatment) {
return res.status(404).send()
}
res.status(200).send(depatment)
} catch (error) {
res.status(500).send(error)
}
});
router.post("/v1/department", async (req, res) => {
try {
const department = new Department(req.body) //this param is for testing the post methode by sending request from postman
await department.save()
} catch (error) {
res.status(500).send(error)
}
});
router.put("/v1/department/:id", async (req, res) => {
//especially useful when testing the put method using postman
const updates = Object.keys(req.body)
const allowedUpdates = ['name', 'email']
const isValideOperations = updates.every((update) => allowedUpdates.includes(update))
if (!isValideOperations) {
return res.status(400).send({ error: 'Invalid updates' })
}
try {
const _id = req.params.id
const department = await Department.findByIdAndUpdate(_id)
if (!department) {
return res.status(404).send()
}
res.send(department)
} catch (error) {
res.status(500).send(error)
}
})
//Safe delete by updating the field isDeleted to true
router.delete('/v1/department/:id', async (req, res) => {
try {
const _id = req.params.id
const department = await Department.findByIdAndUpdate(_id, { isDeleted: true })
if (!department) {
return res.status(400).send()
}
res.status(200).send(department)
} catch (error) {
res.status(500).send(error)
}
})
In the department.js file, you need to export the router:
module.exports = router