Skip to content

Commit

Permalink
finished section 6
Browse files Browse the repository at this point in the history
  • Loading branch information
takuyadev committed Nov 3, 2022
1 parent 73b2cb1 commit 9f38b1c
Show file tree
Hide file tree
Showing 12 changed files with 397 additions and 86 deletions.
9 changes: 3 additions & 6 deletions _data/bootcamps.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@
"housing": true,
"jobAssistance": true,
"jobGuarantee": false,
"acceptGi": true,
"averageCost": 10000
"acceptGi": true
},
{
"_id": "5d713a66ec8f2b88b8f830b8",
Expand All @@ -28,8 +27,7 @@
"housing": false,
"jobAssistance": true,
"jobGuarantee": false,
"acceptGi": true,
"averageCost": 12000
"acceptGi": true
},
{
"_id": "5d725a037b292f5f8ceff787",
Expand All @@ -44,8 +42,7 @@
"housing": false,
"jobAssistance": false,
"jobGuarantee": false,
"acceptGi": false,
"averageCost": 5000
"acceptGi": false
},
{
"_id": "5d725a1b7b292f5f8ceff788",
Expand Down
120 changes: 45 additions & 75 deletions controllers/bootcamps.js
Original file line number Diff line number Diff line change
@@ -1,85 +1,14 @@
const Bootcamp = require('../model/Bootcamp')
const path = require('path')
const asyncHandler = require('../middleware/async')
const ErrorResponse = require('../utils/errorResponse')
const geocoder = require('../utils/geocoder')
const Bootcamp = require('../model/Bootcamp')

// @desc Get all bootcamps
// @route GET /api/v1/bootcamps
// @access Public
exports.getBootcamps = asyncHandler(async (req, res, next) => {
let query;

// Copy req.query
const reqQuery = { ...req.query }

// Fiels to exclude
const removeFields = ['select', 'sort', 'limit']

// Loop over remove fields and delete them from reqQuery
removeFields.forEach(param => delete reqQuery[param])
console.log(reqQuery)

// Create query string
let queryStr = JSON.stringify(req.query)

// Create operators ($gt, $gte, etc.)
queryStr = queryStr.replace(/\b(gt|gte|lt|lte|in)\b/g, match => `$${match}`)

// Finding resources
query = Bootcamp.find(JSON.parse(queryStr))

// Select fields
if (req.query.select) {
const fields = req.query.select.split(',').join(' ')
query.select(fields)
}

// Sort
if (req.query.sort) {
const sortBy = req.query.sort.split(',').join(' ')
query = query.sort(sortBy)
} else {
query = query.sort('-createdAt')
}

// Pagination
const page = parseInt(req.query.page, 10) || 1
const limit = parseInt(req.query.limit, 10) || 25;
const startIndex = (page - 1) * limit
const endIndex = page * limit
const total = await Bootcamp.countDocuments();

query = query.skip(startIndex).limit(limit)

// Executing Query
const bootcamp = await query

// Pagination result
const pagination = {}

if (endIndex < total) {
pagination.next = {
page: page + 1,
limit
}
}

if (startIndex > 0) {
pagination.prev = {
page: page - 1,
limit
}
}

console.log(queryStr)
res
.status(201)
.json({
success: true,
count: bootcamp.length,
pagination,
data: bootcamp,
})
res.status(200).json(res.advancedResults)
})

// @desc Get single bootcamp
Expand Down Expand Up @@ -134,18 +63,59 @@ exports.updateBootcamp = asyncHandler(async (req, res, next) => {
// @route DELETE /api/v1/bootcamps
// @access Private
exports.deleteBootcamp = asyncHandler(async (req, res, next) => {
const bootcamp = await Bootcamp.findByIdAndRemove(req.params.id)
const bootcamp = await Bootcamp.findById(req.params.id)

if (!bootcamp) {
return next(next(new ErrorResponse(`Bootcamp not found with id of ${req.params.id}`, 404)))
}

bootcamp.remove()

res
.status(200)
.json({ success: true, data: {} })

})

// @desc Upload Photo
// @route PUT /api/v1/bootcamps/:id/photo
// @access Private
exports.bootcampPhotoUpload = 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}`, 404))
}

if (!req.files) {
return next(new ErrorResponse(`Please upload a file`, 400))
}

const file = req.files.file

if (!file.mimetype.startsWith('image')) {
return next(new ErrorResponse(`Please upload an image file`, 400))
}

if (file.size > process.env.MAX_FILE_UPLOAD) {
return next(new ErrorResponse(`Please upload an image smaller than ${process.env.MAX_FILE_UPLOAD} bytes`, 400))
}

// Create custom filename
file.name = `photo_${bootcamp._id}${path.parse(file.name).ext}`

file.mv(`${process.env.FILE_UPLOAD_PATH}/${file.name}`, async err => {
if (err) {
return next(new ErrorResponse(`Problem with file upload`, 500))
}
await Bootcamp.findByIdAndUpdate(req.params.id, { photo: file.name })
res.status(200).json({
success: true,
data: file.name
})
})
})

// @desc GET bootcamps within a radius
// @route GET /api/v1/bootcamps/radius/:radius/:distance
// @access Private
Expand Down
112 changes: 112 additions & 0 deletions controllers/courses.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
const Courses = require('../model/Courses')
const asyncHandler = require('../middleware/async');
const ErrorResponse = require('../utils/errorResponse');
const Bootcamp = require('../model/Bootcamp');

// @desc Get all bootcamps
// @route GET /api/v1/courses
// @route GET /api/v1/bootcamps/:bootcampId/courses
// @access Public
exports.getCourses = asyncHandler(async (req, res, next) => {

// If parameter is filled out
if (req.params.bootcampId) {
const courses = await Course.find({ bootcamp: req.params.bootcampId })
return res.status(200).json({
success: true,
count: courses.length,
data: courses
})
} else {
res.status(200).json(res.advancedResults)
}

const courses = await query;

res.status(200).json({
succes: true,
count: courses.length,
data: courses
})
})


// @desc Get single course
// @route GET /api/v1/courses
// @route GET /api/v1/courses/:id
// @access Public
exports.getCourse = asyncHandler(async (req, res, next) => {
const course = await Courses.findById(req.params.id).populate({
path: 'bootcamp',
select: 'name description'
})

if (!course) {
return next(new ErrorResponse(`No course with the id of ${req.params.id}`), 404)
}

res.status(200).json({
succes: true,
data: course
})
})

// @desc Add course
// @route GET /api/v1/bootcamps/:bootcampId/courses
// @access Private
exports.addCourse = asyncHandler(async (req, res, next) => {
req.body.bootcamp = req.params.bootcampId;

const bootcamp = await Bootcamp.findById(req.params.bootcampId)

if (!bootcamp) {
return next(new ErrorResponse(`No bootcamp with the id of ${req.params.bootcampId}`), 404)
}

const course = await Courses.create(req.body)

res.status(200).json({
succes: true,
data: course
})
})

// @desc Update course
// @route PUT /api/v1/courses/:id
// @access Private
exports.updateCourse = asyncHandler(async (req, res, next) => {
let course = await Courses.findById(req.params.id)

if (!course) {
return next(new ErrorResponse(`No course with the id of ${req.params.id}`), 404)
}

course = await Courses.findByIdAndUpdate(req.params.id, req.body, {
new: true,
runValidators: true
})

res.status(200).json({
succes: true,
data: course
})
})

// @desc Delete course
// @route DELETE /api/v1/courses/:id
// @access Private
exports.deleteCourse = asyncHandler(async (req, res, next) => {
const course = await Courses.findById(req.params.id)

if (!course) {
return next(new ErrorResponse(`No course with the id of ${req.params.id}`), 404)
}

await course.remove()

res.status(200).json({
succes: true,
data: {}
})
})

79 changes: 79 additions & 0 deletions middleware/advancedResults.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
const advancedResults = (model, populate) => async (req, res, next) => {
let query;

// Copy req.query
const reqQuery = { ...req.query };

// Fields to exclude
const removeFields = ['select', 'sort', 'page', 'limit'];

// Loop over removeFields and delete them from reqQuery
removeFields.forEach(param => delete reqQuery[param]);

// Create query string
let queryStr = JSON.stringify(reqQuery);

// Create operators ($gt, $gte, etc)
queryStr = queryStr.replace(/\b(gt|gte|lt|lte|in)\b/g, match => `$${match}`);

// Finding resource
query = model.find(JSON.parse(queryStr));

// Select Fields
if (req.query.select) {
const fields = req.query.select.split(',').join(' ');
query = query.select(fields);
}

// Sort
if (req.query.sort) {
const sortBy = req.query.sort.split(',').join(' ');
query = query.sort(sortBy);
} else {
query = query.sort('-createdAt');
}

// Pagination
const page = parseInt(req.query.page, 10) || 1;
const limit = parseInt(req.query.limit, 10) || 25;
const startIndex = (page - 1) * limit;
const endIndex = page * limit;
const total = await model.countDocuments(JSON.parse(queryStr));

query = query.skip(startIndex).limit(limit);

if (populate) {
query = query.populate(populate);
}

// Executing query
const results = await query;

// Pagination result
const pagination = {};

if (endIndex < total) {
pagination.next = {
page: page + 1,
limit
};
}

if (startIndex > 0) {
pagination.prev = {
page: page - 1,
limit
};
}

res.advancedResults = {
success: true,
count: results.length,
pagination,
data: results
};

next();
};

module.exports = advancedResults;
Loading

0 comments on commit 9f38b1c

Please sign in to comment.