Node.js and Express.js part 4

const errorHandler = (err, req, res, next) => {res.status(500).json({sucess:false,error:err.message});}module.exports = errorHandler;
const express = require('express');
const dotenv = require('dotenv');
const morgan = require('morgan');
const connectDB = require('./config/db');
const errorHandler = require('./middleware/error');
// Load env vars
dotenv.config({ path: './config/config.env' });
//connect to db
connectDB();
// Route files
const bootcamps = require('./routes/bootcamps');
const app = express();//Body parser
app.use(express.json());
// dev logging middleware
if (process.env.NODE_ENV == 'development') {
app.use(morgan('dev'));
}
// Mount routers
app.use('/api/v1/bootcamps', bootcamps);
app.use(errorHandler);const PORT = process.env.PORT || 5000;const server = app.listen(
PORT,
console.log(`server running in ${process.env.NODE_ENV} mode on PORT ${PORT}`)
);
//handle unhandled promise rejection
process.on('unhandledRejection', (err, promise) => {
console.log(`Error: ${err.message}`);
//console.log('dsds');
// Close server & exit process
//server.close(() => process.exit(1));
});
//mongodb://localhost:27017/dev-learn
exports.getBootcamp = async (req,res,next) => {
try {
const bootcamp = await Bootcamp.findById(req.params.id);
if(!bootcamp){
return res.status(400).json({sucess:false});
}
res.status(200).json({success:true,data:bootcamp});
} catch (err) {
//res.status(400).json({sucess:false});
next(err);
}
};
class ErrorResponse extends Error {constructor(message, statusCode) {super(message);this.statusCode = statusCode;//Error.captureStackTrace(this, this.constructor);}}module.exports = ErrorResponse;
const errorHandler = (err, req, res, next) => {
res.status(err.statusCode || 500).json({
sucess:false,
error:err.message || 'Server error'
});
};
module.exports = errorHandler;
exports.getBootcamp = async (req,res,next) => {
try {
const bootcamp = await Bootcamp.findById(req.params.id);
if(!bootcamp){
return next(new ErrorResponse(`Bootcamp not found with id of ${req.params.id}`,400));
}
res.status(200).json({success:true,data:bootcamp});
} catch (err) {
//res.status(400).json({sucess:false});
next(new ErrorResponse(`Bootcamp not found with id of ${req.params.id}`,400));
}
};
const errorHandler = (err, req, res, next) => {let error = { ...err };error.message = err.message;//Mongoose bad ObjectId
if (err.name === 'CastError') {
const message = `Resource not found ${err.value}`;
error = new ErrorResponse(message, 404);
}
// // Mongoose duplicate key
if (err.code === 11000) {
const message = 'Duplicate field value entered';
error = new ErrorResponse(message, 400);
}
// // Mongoose validation error
if (err.name === 'ValidationError') {
const message = Object.values(err.errors).map(val => val.message);
error = new ErrorResponse(message, 400);
}
res.status(error.statusCode || 500).json({
sucess:false,
error: error.message || 'Server error'
});
};
const Bootcamp = require('../models/Bootcamp');
const ErrorResponse = require('../utils/errorResponse');
exports.getBootcamps = async (req,res,next) => {
try {
const bootcamps = await Bootcamp.find();
res.status(200).json({success:true,count:bootcamps.length,data:bootcamps});
//next(err);
} catch (err) {
next(err);
}
};
exports.getBootcamp = async (req,res,next) => {
try {
const bootcamp = await Bootcamp.findById(req.params.id);
if(!bootcamp){
return next(new ErrorResponse(`Bootcamp not found with id of ${req.params.id}`,400));
}
res.status(200).json({success:true,data:bootcamp});
} catch (err) {
//res.status(400).json({sucess:false});
next(err);
}
};
exports.createBootcamp = async (req,res,next) => {
try{
const bootcamp = await Bootcamp.create(req.body);
res.status(201).json({
success:true,
data:bootcamp
});
} catch (err){
next(err);
}
};
exports.updateBootcamp = async (req,res,next) => {
try{
const bootcamp = await Bootcamp.findByIdAndUpdate(req.params.id,req.body,{
new:true,
runValidators:true
});
if(!bootcamp){
return next(new ErrorResponse(`Bootcamp not found with id of ${req.params.id}`,400));
}
res.status(200).json({sucess:true,data:bootcamp});
} catch(err){
next(err);
}
};
exports.deleteBootcamp = async (req,res,next) => {
try{
const bootcamp = await Bootcamp.findByIdAndDelete(req.params.id);
if(!bootcamp){
return next(new ErrorResponse(`Bootcamp not found with id of ${req.params.id}`,400));
}
res.status(200).json({sucess:true,data:{}});
} catch(err){
next(err);
}
};

DRY (Don’t repeat yourself)

so in our controllers/bootcamps.js we have same catch block everywhere, can we do something about it? yes

const asyncHandler = fn => (req, res, next) =>Promise.resolve(fn(req, res, next)).catch(next);module.exports = asyncHandler;
const Bootcamp = require('../models/Bootcamp');
const asyncHandler = require('../middleware/async');
const ErrorResponse = require('../utils/errorResponse');
exports.getBootcamps = asyncHandler(async (req, res, next) => {
const bootcamps = await Bootcamp.find();
res.status(200).json({success:true,count:bootcamps.length,data:bootcamps});
//next(err);
});exports.getBootcamp = asyncHandler(async (req,res,next) => {
const bootcamp = await Bootcamp.findById(req.params.id);
if(!bootcamp){
return next(new ErrorResponse(`Bootcamp not found with id of ${req.params.id}`,400));
}
res.status(200).json({success:true,data:bootcamp});
});exports.createBootcamp = asyncHandler(async (req,res,next) => {
const bootcamp = await Bootcamp.create(req.body);
res.status(201).json({
success:true,
data:bootcamp
});
});
exports.updateBootcamp = asyncHandler(async (req,res,next) => {
const bootcamp = await Bootcamp.findByIdAndUpdate(req.params.id,req.body,{
new:true,
runValidators:true
});
if(!bootcamp){
return next(new ErrorResponse(`Bootcamp not found with id of ${req.params.id}`,400));
}
res.status(200).json({sucess:true,data:bootcamp});

});
exports.deleteBootcamp = asyncHandler(async (req,res,next) => {
const bootcamp = await Bootcamp.findByIdAndDelete(req.params.id);
if(!bootcamp){
return next(new ErrorResponse(`Bootcamp not found with id of ${req.params.id}`,400));
}
res.status(200).json({sucess:true,data:{}});

});
npm i slugify
const slugify = require('slugify');
// Create bootcamp slug from the nameBootcampSchema.pre('save', function(next) {this.slug = slugify(this.name, { lower: true });next();});

MapQuest API GeoJSON location

mainly used to give the location fields that we added in our model

npm i node-geocoder
GEOCODER_PROVIDER=mapquestGEOCODER_API_KEY=yourconsumerkey
const NodeGeocoder = require('node-geocoder');const options = {
provider: process.env.GEOCODER_PROVIDER,
httpAdapter: 'https',
apiKey: process.env.GEOCODER_API_KEY,
formatter: null
};
const geocoder = NodeGeocoder(options);module.exports = geocoder;
const geocoder = require('../utils/geocoder');
// Geocode & create location field
BootcampSchema.pre('save', async function(next) {
const loc = await geocoder.geocode(this.address);
this.location = {
type: 'Point',
coordinates: [loc[0].longitude, loc[0].latitude],
formattedAddress: loc[0].formattedAddress,
street: loc[0].streetName,
city: loc[0].city,
state: loc[0].stateCode,
zipcode: loc[0].zipcode,
country: loc[0].countryCode
};
// Do not save address in DB
this.address = undefined;
next();
});
{
"name": "ModernTech Bootcamp",
"description": "ModernTech has one goal, and that is to make you a rockstar developer and/or designer with a six figure salary. We teach both development and UI/UX",
"website": "
https://moderntech.com",
"phone": "(222) 222-2222",
"email": "
enroll@moderntech.com",
"address": "220 Pawtucket St, Lowell, MA 01854",
"careers": ["Web Development", "UI/UX", "Mobile Development"],
"housing": false,
"jobAssistance": true,
"jobGuarantee": false,
"acceptGi": true
}

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store