node js : test rest API - node.js

i'm new learner in backend node js ... in my code below i created an API for questions and it contains get,post,delete and edit
i wanted to test it using the extension rest client in VS code but when i type Get http://localhost:3000/api in route.rest file to test it,it stucks on waiting
is there a way to know if my API works good and can somebody please help me if i have mistake below?
thanks in advance
//server.js
// #ts-nocheck
const express = require('express');
const morgan = require('morgan');
const mongoose = require('mongoose');
const dotenv = require('dotenv');
const jwt = require('jsonwebtoken');
const questionRoutes = require('./routes/subscribers');
const cors = require('cors');
const http = require('http');
// Has to be move but later
const multer = require("multer");
const Question = require('./models/subscriber');
// express app
const app = express();
// Explicitly accessing server
const server = http.createServer(app);
// corsfffffffff
app.use(cors());
dotenv.config();
const dbURI = process.env.MONGO_URL || "mongodb://localhost:27017/YourDB";
mongoose.connect(dbURI, { useNewUrlParser: true, useUnifiedTopology: true })
.then(result => server.listen(process.env.PORT || 3000) )
.catch(err => console.log(err));
// register view engine
app.set('view engine', 'ejs');
app.use(express.json);
// middleware & static files
app.use(express.static('public'));
app.use(express.urlencoded({ extended: true }));
app.use(morgan('dev'));
app.use((req, res, next) => {
res.locals.path = req.path;
next();
});
// routes
// question routes
app.use('/questions' , questionRoutes );
// 404 page
app.use((req, res) => {
res.status(404).render('404', { title: '404' });
});
//questionRoute.js
const express = require('express');
const questionController = require('../controllers/questionCon');
const questionApiController = require('../controllers/questionApiController');
const router = express.Router();
// API Routing
router.get('/api/', questionApiController.get_questions);
router.post('/api/add', questionApiController.create_question);
router.get('/api/:id', questionApiController.get_question);
router.delete('/api/delete/:id', questionApiController.delete_question);
router.put('/api/update/:id', questionApiController.update_question);
// EJS Routing for GUI
router.get('/create', questionController.question_create_get);
router.get('/', questionController.question_index);
router.post('/', questionController.question_create_post);
router.get('/:id', questionController.question_details);
router.delete('/:id', questionController.question_delete);
module.exports = router;
//question.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const questionSchema = new Schema({
questionTitle: {
type: String,
required: true,
},
description: {
type: String,
},
price: {
type: Number,
},
});
const Question = mongoose.model('Question', questionSchema);
module.exports = Question;
//questionAPIcontroller
const Question = require('../models/subscriber');
const validators = require('../validators');
let questionApiController = {
// Get a single question
get_question : async (req , res) => {
const id = req.params.id;
try {
const question = await Question.findById(id,(err, question) => {
if (err) return res.status(400).json({response : err});
res.send("hello")
res.status(200).json({response : question})
console.log("hello")
})
} catch (err) {
res.status(400).json(err);
}
},
// Get all the questions
get_questions: async (req , res) => {
try {
const questions = await Question.find((err, questions) => {
if (err) return res.status(400).json({response : err});
res.status(200).json({response : questions})
})
} catch (err) {
res.status(400).json(err);
}
},
// Create a question
create_question : async (req , res) => {
const {error} = validators.postQuestionValidation(req.body);
if(error) return res.status(400).json({ "response" : error.details[0].message})
try {
const question = await new Question(req.body);
question.save((err, question) => {
if (err) return res.status(400).json({response : err});
res.status(200).json({response : " Question created Successfully"})
});
} catch (err) {
res.status(400).json(err);
}
},
// Delete question
delete_question : async (req , res) => {
const id = req.params.id;
var questionExist = false;
var userId ;
const question = await Question.findById(id).then(result => {
questionExist = true;
userId = result.owner;
}).catch(err => {
questionExist = false;
res.status(400).json({response : err });
});
if(questionExist){
try {
Question.findByIdAndRemove(id ,(err, question) => {
// As always, handle any potential errors:
if (err) return res.json({response : err});
// We'll create a simple object to send back with a message and the id of the document that was removed
// You can really do this however you want, though.
const response = {
message: "Question successfully deleted",
id: question._id
};
return res.status(200).json({response : response });
});
} catch (err) {
res.status(400).json(err);
}
}
else {
return res.status(400).send( { "response" : "A question with that id was not find."});
}
},
// Update question
update_question : async (req , res) => {
const id = req.params.id;
Question.findByIdAndUpdate(id,req.body,
function(err, result) {
if (err) {
res.status(400).json({response : err});
} else {
res.status(200).json({response : "Question Updated"});
console.log(result);
}
})
},
// Get question's questions
}
module.exports = questionApiController
//questionController
const Question = require('../models/subscriber');
const question_index = (req, res) => {
Question.find().sort({ createdAt: -1 })
.then(result => {
res.render('index', { questions: result, title: 'All questions' });
})
.catch(err => {
console.log(err);
});
}
const question_details = (req, res) => {
const id = req.params.id;
Question.findById(id)
.then(result => {
res.render('details', { question: result, title: 'Question Details' });
})
.catch(err => {
console.log(err);
res.render('404', { title: 'Question not found' });
});
}
const question_create_get = (req, res) => {
res.render('create', { title: 'Create a new question' });
}
const question_create_post = (req, res) => {
const question = new Question(req.body);
question.save()
.then(result => {
res.redirect('/questions');
})
.catch(err => {
console.log(err);
});
}
const question_delete = (req, res) => {
const id = req.params.id;
Question.findByIdAndDelete(id)
.then(result => {
res.json({ redirect: '/questions' });
})
.catch(err => {
console.log(err);
});
}
module.exports = {
question_index,
question_details,
question_create_get,
question_create_post,
question_delete
}

change code
app.use(express.json);
to
app.use(express.json());

Related

Mongoose suddenly returning empty []

Been following trying to get a mongoose server setup, and it briefly worked, but now it's not for some reason and I honestly have no idea what's going on. No matter what I do, it's returning a blank []?
Collection is "users" all lowercase. Config is in other files. Like I said it has worked before for me briefly and I have no clue why it suddenly stopped.
EDIT - The user object is undefined so it's not even pulling the data from the db for some reason?
server.js
const express = require('express')
const cors = require('cors')
const app = express()
var corsOptions = {
origin: "http://localhost:8080"
}
app.use(cors(corsOptions))
app.use(express.json())
app.use(express.urlencoded({extended:true}))
const db = require('./app/models')
db.mongoose
.connect(db.url, {
useNewUrlParser: true,
useUnifiedTopology: true
})
.then(() => {
console.log("Connected to the database!");
})
.catch(err => {
console.log("Cannot connect to the database!", err);
process.exit();
});
app.get("/", (req, res) => {
res.json({ message: "Welcome to server." });
});
require("./app/routes/user.routes")(app);
const PORT = process.env.PORT || 8080;
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}.`);
});
model
module.exports = mongoose => {
var schema = mongoose.Schema(
{
id: Number,
ref: String,
name: String,
achieves: Array,
total: Number
},
{ timestamps: true }
);
schema.method("toJSON", function() {
const { __v, _id, ...object } = this.toObject();
object.id = _id;
return object;
});
const User = mongoose.model("users", schema);
return User;
};
findAll method in controller
exports.findAll = (req, res) => {
const name = req.query.name;
var condition = name ? { name: { $regex: new RegExp(name), $options: "i" } } : {};
User.find(condition)
.then(data => {
res.send(data);
console.log(data);
})
.catch(err => {
res.status(500).send({
message:
err.message || "Some error occurred while retrieving users."
});
});
};
Try this one at query:
{name: {$regex : `.*${name}.*`, $options: "i"}}

API for making query searches not working

I'm trying to fetch all records from MongoDB starting with the Alphabet S but every time I try doing so, it returns nothing but []. I'm using the Params tab on Postman to do this.
The code that I have written is below as well as a snip from Postman to make the question more understandable. I'm pretty sure that the API I have written to perform this has something wrong with it.
The Model file
const mongoose = require('mongoose');
const entry = new mongoose.Schema({
name : {
type : String,
},
collegeName : {
type : String,
},
location : {
type : String,
}
});
const enter = mongoose.model("Student", entry);
module.exports = enter;
index.js
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const mongo = require('mongodb');
const dataModel = require('./model/model');
const MongoClient = mongo.MongoClient;
const uri = "mongodb+srv://coolhack069:XzC6N7dOyUeQl8M9#cluster0.kz6v9.mongodb.net/assignment?retryWrites=true&w=majority";
const client = new MongoClient(uri, { useNewUrlParser: true, useUnifiedTopology: true });
app.use(express.json());
app.use(bodyParser.json());
const port = 3001;
app.get('/api/get', (req, res) => {
client.connect(err => {
if(err) {
throw err;
}
const collection = client.db('assignment').collection('data');
const fetchedData = {};
collection.find(fetchedData).toArray(function(err, result) {
res.send(result);
client.close();
});
})
});
app.get('/api/getStudentDetails', (req, res) => { //The API I have written to query through the Database
client.connect(err => {
if(err) {
throw err;
}
const collection = client.db('assignment').collection('data');
const fetchedData = new dataModel({
name : req.params.name
});
collection.find(fetchedData).toArray(function(err, result) {
res.send(result);
client.close();
})
})
});
app.post('/api/add', (req, res) => { //To add Data
const name = req.body.name;
const collegeName = req.body.collegeName;
const location = req.body.location;
client.connect(err => {
if(err) {
throw err;
}
const collection = client.db('assignment').collection('data');
const storeData = new dataModel({
name : name,
collegeName : collegeName,
location : location
});
console.log(storeData);
collection.insertOne(storeData, function(err, result) {
res.json({
result : "Success"
});
console.log(err);
client.close();
});
})
});
app.listen(port, () => {
console.log(`Application running at http://localhost:${port}`)
})
The Screenshot from Postman
Your find condition is not correct:
const fetchedData = new dataModel({ // ???
name : req.params.name
});
collection.find(fetchedData).toArray(function(err, result) {
res.send(result);
client.close();
})
??? - I guest your meaning is const fetchedData = { name: req.params.name}; - Find every document which have name is req.params.name (S - in your case). But there is no document has name is S in your collection, then it returns [].
If you want to find the documents with S as the first character of their name, you can use Regex syntax:
const query = {
name : new RegExp('^' + req.params.name, 'i'), // i - case insensitive, => /^S/i
};
collection.find(query).toArray(function(err, result) {
res.send(result);
client.close();
})

error while using deleteOne in app.delete function in Node.js

** trying to use the app.delete and trying to delete document from mondo db using delete one...it keep throwing errror. how to solve this error ? **
``` require('dotenv').config()
const express = require('express')
const app = express()
const PORT = process.env.PORT || 5001
const connectDB = require('./config/db')
const errorHandler = require('./middleware/error')
const Product =require('./models/product')
const cors = require('cors')
// Connect DB
connectDB()
// Middleware
app.use(cors())
app.use(express.json())
app.use('/auth', require('./routes/authRoutes'))
app.use('/admin', require('./routes/adminRoutes'))
app.use('/customer', require('./routes/customerRoutes'))
app.use('/staff', require('./routes/staffMemberRoutes'))
// error handler - should be *last* piece of middleware
app.use(errorHandler)
app.get('/all-products', (req, res) => {
Product.find({}, (error, posts) => {
if(error) {
res.json({error: 'Unable to fetch products!'})
} else {
res.json(posts)
}
})
})
app.post ('/add-products',(req,res) =>{
console.log("add-products has been fired")
const imageurl = req.body.imageurl
const title = req.body.title
const description = req.body.description
const rate = req.body.rate
const category = req.body.category
const subcategory = req.body.subcategory
let product = new Product({
imageurl: imageurl,
title: title,
description: description,
rate: rate,
category: category,
subcategory: subcategory,
})
product.save((error) => {
if(error) {
res.json({error: 'Unable to save the product!'})
} else {
res.json({success: true, message: 'New product Saved'})
}
})
})
app.delete('/product/:productId', (req, res) => {
const productId = req.params.productId
Product.deleteOne({
_id: productId
}, (error, result) => {
if(error) {
res.json({error: 'Unable to delete product'})
} else {
res.json({success: true, message: 'Product deleted successfully!'})
}
})
})
app.put('/update-product/:productId', (req, res) => {
const productId = req.params.productId
const imageurl = req.body.imageurl
const title = req.body.title
const description = req.body.description
const rate = req.body.rate
const category = req.body.category
const subcategory = req.body.subcategory
const updatedProduct = {
imageurl: imageurl,
title: title,
description: description,
rate: rate,
category: category,
subcategory: subcategory,
}
Product.findByIdAndUpdate(productId, updatedProduct, (error, result) => {
if(error) {
res.json({error: 'Unable to updated the Product'})
} else {
res.json({success: true, message: 'Product updated successfully!'})
}
})
})
const server = app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`)
})
// makes giant server errors concise and simple to read
process.on('unhandledRejection', (err, promise) => {
console.log(`Logged Error: ${err}`)
server.close(() => process.exit(1))
})```
if(error) {
res.json({error: 'Unable to delete product'})
}
In this line, replace res.json with:
res.json({error})
And then comment here the output (error message on the console)

Where did I go wrong with passport-jwt setup?

I tried to add passport-jwt to my MEVN-stack application, login is successful, but when app tries to redirect to home page after login, I get 401 Unauthorized error in console. I pass token as value of Authorization header in get request on the home page, but it did not help.
This is the code of server.js (the entrypoint of server side):
const express = require('express');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
const cors = require('cors');
const morgan = require('morgan');
const fs = require('fs');
const jwt = require('jsonwebtoken');
const passport = require('passport');
const passportJWT = require('passport-jwt');
const ExtractJWT = passportJWT.ExtractJwt;
const JWTStrategy = passportJWT.Strategy;
const jwtOptions = {};
jwtOptions.jwtFromRequest = ExtractJWT.fromAuthHeaderWithScheme('jwt');
jwtOptions.secretOrKey = 'movieratingapplicationsecretkey';
const app = express();
const router = express.Router();
const User = require('./models/User');
app.use(morgan('combined'));
app.use(bodyParser.json());
app.use(cors());
app.use(passport.initialize());
passport.use(new JWTStrategy(jwtOptions, (jwt_payload, done) => {
User.findOne({ id: jwt_payload.id }, (err, user) => {
if (err) {
return done(err, false);
}
if (user) {
return done(null, user);
} else {
return done(null, false);
}
});
}));
mongoose.connect('mongodb://localhost/movie_rating_app', {
useNewUrlParser: true,
useUnifiedTopology: true,
})
.then(() => {
console.log('Connection is established');
})
.catch((err) => {
console.error(`App starting error: ${err.stack}`);
});
// include controllers
fs.readdirSync('controllers').forEach(file => {
if (file.substr(-3) === '.js') {
const route = require(`./controllers/${file}`)
route.controller(app)
}
})
router.get('/', (req, res) => {
res.json({ message: 'API was initialized!' });
});
const port = process.env.API_PORT || 8081;
app.use('/', router);
app.listen(port, () => {
console.log(`api running on port ${port}`);
});
This is the movies.js controllerm, which contains passport.authenticate() method in get request:
const Movie = require('../models/Movie')
const Rating = require('../models/Rating')
const passport = require('passport')
module.exports.controller = app => {
// fetch all movies
app.get(
'/movies',
passport.authenticate('jwt', { session: false }),
(req, res) => {
Movie.find({}, 'name description release_year genre', (error, movies) => {
if (error) console.error(error)
res.send(movies);
})
})
// fetch a single movie
app.get('/movies/:id', (req, res) => {
Movie.findById(req.params.id, 'name description release_year genre', (error, movie) => {
if (error) console.error(error)
res.send(movie);
})
})
}
This is the users.js controller:
const User = require('../models/User');
const passportJWT = require('passport-jwt');
const jwt = require('jsonwebtoken');
const ExtractJwt = passportJWT.ExtractJwt;
const jwtOptions = {};
jwtOptions.jwtFromRequest = ExtractJwt.fromAuthHeaderWithScheme('jwt');
jwtOptions.secretOrKey = 'thisisthesecretkey';
module.exports.controller = app => {
// register a user
app.post('/users/register', (req, res) => {
const newUser = new User({
name: req.body.name,
email: req.body.email,
password: req.body.password,
})
User.createUser(newUser, (error, user) => {
if (error) {
res.status(422).json({
message: 'Something went wrong. Please try again after some time'
})
}
res.send({ user });
})
})
// login user
app.post('/users/login', (req, res) => {
if (req.body.email && req.body.password) {
const email = req.body.email,
password = req.body.password;
User.getUserByEmail(email, (err, user) => {
if (!user) {
res.status(404).json({ message: 'The user does not exist' })
} else {
User.comparePassword(password, user.password, (error, isMatch) => {
if (error) throw error;
if (isMatch) {
const payload = { id: user.id };
const token = jwt.sign(payload, jwtOptions.secretOrKey);
res.json({ message: 'ok', token })
} else {
res.status(401).json({ message: 'The password is incorrect' })
}
})
}
})
}
})
}
This is the script part of Home.vue, when I try to receive response:
<script>
import axios from 'axios';
import MovieCard from '#/components/MovieCard.vue';
export default {
name: 'Home',
components: {
MovieCard,
},
data: () => ({
movies: [],
}),
mounted() {
this.fetchMovies();
},
methods: {
async fetchMovies() {
const token = window.localStorage.getItem('auth');
return axios({
method: 'get',
url: 'http://localhost:8081/movies',
headers: {
Authorization: `JWT ${token}`,
'Content-Type': 'application/json',
},
})
.then((response) => {
console.log(response);
});
// return axios.get('http://localhost:8081/movies')
// .then(({ data }) => {
// this.movies = data;
// })
// .catch((error) => {
// console.error(error);
// });
},
},
};
</script>
Please don't mark my question as duplicate, because I have already tried some advices such as change ExtractJWT.fromAuthHeaderWithScheme('jwt') to ExtractJWT.fromAuthHeaderWithScheme('bearer'), but it did not help me.
How to fix 401 error?
I replaced all ExtractJwt.fromAuthHeaderWithScheme('jwt') with ExtractJwt.fromAuthHeaderAsBearerToken(), and set all jwtOptions.secretOrKey values as 'thisisthesecretkey'. 401 error does not exist now

How to create a Mongo database to Node.js?

I have created the backend operations using Node.js / MongoDB and created services for them, but when I run the server it indicates that I've connected successfully, but I can't see a database in Robo 3T.
Here is what I coded:
DBConfig.js
var mongoose = require ('mongoose');
var Schema = mongoose.Schema;
var UserSchema = new Schema({
name : {
type : String,
require : true
},
address : {
type : String,
require : true
}
});
mongoose.model("User", UserSchema);
module.exports = mongoose;
mongoose.connect('mongodb://127.0.0.1:27017/TestDB4', function(err){
if(err)
{
console.log(err);
process.exit(-1);
}
console.log("Connected to the db")
});
I can't see an error. Why isn't the DB created?
check your User.Controller.js as this below,
var mongoose = require('../DBSchema/SchemaMapper');
var UserSchema = mongoose.model('User');
var UserController = function(){
this.insert = (data) => {
return new Promise((resolve, reject) => {
var user = new UserSchema({
userName: data.userName,
password: data.password
});
user.save().then(() => {
resolve({status: 200, message: "Added new user"});
}).catch(err => {
reject({status: 500, message: "Error:- "+err});
})
})
}
this.update = (id, data) => {
return new Promise((resolve, reject) => {
UserSchema.update({_id: id}, data).then(() => {
resolve({status: 200, message: "update user"});
}).catch(err => {
reject({status: 500, message: "Error:- " + err});
})
})
}
this.searchAll = () => {
return new Promise((resolve, reject) => {
UserSchema.find().exec().then((data) => {
resolve({status: 200, data: data});
}).catch(err => {
reject({status: 500, message: "Error:- " + err});
})
})
}
this.search = (id) => {
return new Promise((resolve, reject) => {
UserSchema.find({_id:id}).exec().then(user => {
resolve({status: 200, data: user});
}).catch(err => {
reject({status: 500, message: "Error:- " + err});
})
})
}
this.delete = (id) => {
return new Promise((resolve, reject) => {
UserSchema.remove({_id:id}).then(() => {
resolve({status: 200, message: "remove user"});
}).catch(err => {
reject({status: 500, message:"Error:- " + err});
})
})
}
}
module.exports = new UserController();
And User.Route.js as below,
var express = require('express');
var router = express.Router();
var Controller = require('./User.Controller');
router.post('/', (req, res) => {
Controller.insert(req.body).then(data => {
res.status(data.status).send({message: data.message});
}).catch(err => {
res.status(err.status).send({message: err.message});
})
});
router.put('/:id', (req, res) => {
Controller.update(req.params.id, req.body).then(data => {
res.status(data.status).send({message: data.message});
}).catch(err => {
res.status(err.status).send({message: err.message});
})
});
router.get('/', (req, res) => {
Controller.searchAll().then(data => {
res.status(data.status).send({data: data.data});
}).catch(err => {
res.status(err.status).send({message: err.message});
});
});
router.get('/:id', (req, res) => {
Controller.search(req.params.id).then(data => {
res.status(data.status).send({data: data.data});
}).catch(err => {
res.status(err.status).send({message: err.message});
});
});
router.delete('/:id', (req, res) => {
Controller.delete(req.params.id).then(data => {
res.status(data.status).send({message: data.message});
}).catch(err => {
res.status(err.status).send({message: err.message});
})
})
module.exports = router;
check your app.js as follows
const Express = require("express");
const BodyParser = require("body-parser");
const Routes = require("./Routes");
const Cors = require("cors");
const app = Express();
app.use(Cors());
app.use(BodyParser.urlencoded({ extended: false }));
app.use(BodyParser.json());
app.use('/', Routes);
app.listen(8083, 'localhost', (err) => {
if(err) {
console.log(err);
process.exit(-1);
}
console.log("Server listen port 8083");
});
and Routes.js as follows,
var Express = require("express");
var Routes = Express.Router();
var UserRoute = require('./src/User/User.Route');
var CommentRoute = require('./src/Comment/Comment.Route');
Routes.use('/user/', UserRoute);
Routes.use('/comment/', CommentRoute);
module.exports = Routes;

Resources