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.
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'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)
}
});
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
I'm receiving an invalid inputs error on my signup POST request on Postman. I've checked my User Model attributes but can't seem to find exactly which input(s) is/are being called invalid. Here is my model, controller, route. and app.js. Kindly take a look.
App
const express = require('express');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
const usersRoutes = require('./routes/users-routes');
const postsRoutes = require('./routes/posts-routes');
const HttpError = require('./models/http-error');
const app = express();
app.use(bodyParser.json());
app.use('/api/users', usersRoutes);
app.use('/api/posts', postsRoutes);
app.use((req, res, next) => {
const error = new HttpError('Could not find this route.', 404);
throw error;
})
app.use((error, req, res, next) => {
if (res.headerSent) {
return next(error);
}
res.status(error.code || 500)
res.json({ message: error.message || 'An unknown error occurred!' });
});
const connectUrl = 'hidden';
const connectConfig = {
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true
}
mongoose
.connect(connectUrl, connectConfig)
.then(() => {
app.listen(5000);
})
.catch(err => {
console.log(err);
});
User model
const userSchema = new Schema({
username: { type: String, required: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
avatarUrl: { type: String, required: true },
posts: [{ type: mongoose.Types.ObjectId, required: true, ref: 'Post' }]
});
Users controller
const signup = async (req, res, next) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return next(
new HttpError('Invalid inputs passed, please check your data.', 422)
);
}
const { username, email, password } = req.body;
let existingUser
try {
existingUser = await User.findOne({ email: email })
} catch (err) {
const error = new HttpError('Signing up failed, please try again later.', 500);
return next(error);
}
if (existingUser) {
const error = new HttpError('User exists already, please login instead.', 422);
return next(error);
}
const createdUser = new User({
username,
email,
password,
avatarUrl: 'https://images.pexels.com/photos/406014/pexels-photo-406014.jpeg?auto=compress&cs=tinysrgb&dpr=3&h=750&w=1260',
posts: []
});
try {
await createdUser.save();
} catch (err) {
const error = new HttpError('Signup failed, please try again.', 500);
return next(error);
}
res.status(201).json({ user: createdUser.toObject({ getters: true })});
}
User routes
router.post(
'/signup',
[
check('username').not().isEmpty(),
check('email').normalizeEmail().isEmail(),
check('password').isLength({ min: 6 })
],
usersController.signup
);
Postman
Make sure you using body parser in your middleware:
app.use(express.json())
app.use(express.urlencoded({ extended: true }))
Thank you #SuleymanSah for the answer (sorry, I don't know how to mark your comment above as the answer)
The issue was that the Headers box for Content-Type: application/json on Postman was unchecked. Checking the box solved the invalid inputs issue.
I created a small project with node+express+mongodb
This is where i call the create user:
const express = require("express");
const User = require("../models/user");
const router = express.Router();
router.post("/register", async (req, res) => {
try {
const user = await User.create(req.body);
return res.send({ user });
} catch (e) {
return res.status(400).send({ error: "Registration failed" });
}
});
module.exports = app => app.use("/auth", router);
and here is the Schema for the user:
const mongoose = require("mongoose");
const UserSchema = new mongoose.Schema({
name: {
type: String,
require: true
},
email: {
type: String,
require: true,
unique: true,
lowercase: true
},
password: {
type: String,
require: true,
select: false
},
createdAt: {
type: Date,
default: Date.now
}
});
const User = mongoose.model("User", UserSchema);
module.exports = User;
But when o make the resquest, it nevers get a response, it waits forever. And when o take out the await from the request, it gets an empty response { "user": {}}
I'm kind lost looking the mongoose documentation (the ideia is to make a simple rest api, i'm used with python, but looking to learn node)
You have to create a new user from User Model as follows:
const express = require("express");
const User = require("../models/user");
const router = express.Router();
router.post("/register", async (req, res) => {
try {
var user = new User(request.body);
var result = await user.create();
return res.send({ result });
} catch (e) {
return res.status(400).send({ error: "Registration failed" });
}
});
module.exports = app => app.use("/auth", router);