I am trying to make API for restaurants and developed its controller and model as shown below.
Controller (restaurantData.js)
const restaurantData = require('../Models/restaurantData');
exports.getRestaurantData = (req, res) => {
console.log(req.params.city_id.toString())
restaurantData.find({
city_id: req.params.city_id.toString()
}).then(result => {
res.status(200).json({
message: "Restaurant Data",
restaurants: result
});
}).catch(error => {
res.status(500).json({
message: error
});
});
}
Model (restaurantData.js)
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const restaurantSchema = new Schema({
_id: {
type: Number,
required: true
},
name: {
type: String,
required: true
},
city_name:{
type: String,
required: true
},
city_id: {
type: String,
required: true
},
location_id: {
type: Number,
required: true
},
area: {
type: Number,
required: true
},
locality:{
type: String,
required: true
},
thumb: {
type: String,
required: true
},
cost:{
type: Number,
required: true
},
address:{
type: String,
required: true
},
mealtype:{
type: Number,
required: true
},
name:{
type: String,
required: true
},
cuisine:{
type: Number,
required: true
},
type:{
type: Array,
required: true
},
Cuisine:{
type: Array,
required: true
}
});
module.exports = mongoose.model('restaurantData', restaurantSchema, 'restaurantData');
router.js
const express = require('express');
const restaurantController = require('../Controllers/restaurantData');
const router = express.Router();
router.get('/restaurantData/:cityID',restaurantController.getRestaurantData);
module.exports = router;
app.js
const express = require('express');
const bodyparser = require('body-parser');
const mongoose = require('mongoose');
const apiRouter = require('./Routes/router');
const port = 4005;
const app = express();
app.use(bodyparser.json());
app.use((req, res, next) => {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST');
res.setHeader('Access-Control-Allow-Headers','Content-Type, Authorization');
next();
});
app.use('/api', apiRouter);
mongoose.connect(
'mongodb://127.0.0.1:27017/sampleRestaurant',
{ useNewUrlParser: true, useUnifiedTopology: true }
).then(success => {
console.log('Connected to MongoDB');
app.listen(port, () => {
console.log(`Server started at port ${port}`);
});
}).catch(error => {
console.log(error);
});
Problem is while running on Postman its showing the error "Cannot GET /api/restaurantData". Please share some ideas.
I found an error in your model where you ask for
req.params.city_id.toString()
which is not correct and necesary to convert to an String.
you should use this instead:
const restaurantData = require('../Models/restaurantData');
exports.getRestaurantData = (req, res) => {
const cityId = req.params.cityID;
console.log(cityId)
restaurantData.find({
city_id: cityId
}).then(result => {
res.status(200).json({
message: "Restaurant Data",
restaurants: result
});
}).catch(error => {
res.status(500).json({
message: error
});
});
}
the reason is because you require the parameter city_id instead of cityID, the one you use in your route:
router.get('/restaurantData/:cityID',restaurantController.getRestaurantData);
Related
This is my code to automatically feed data into my database. The connection is correct as if we comment out the await Product.deleteMany() but when the following code is compiled and run, we get the error "TypeError: Product.deleteMany is not a function". Please help.
Code:
require('dotenv').config()
const connectDB = require('./db/connect')
const Product = require('./models/product')
const jsonProducts = require('./products.json')
const start = async () => {
try {
await connectDB(process.env.MONGO_URI)
await Product.deleteMany()
await Product.create(jsonProducts)
console.log('Success!!!!')
process.exit(0)
} catch (error) {
console.log(error)
process.exit(1)
}
}
start()
ConnectDB code:
const mongoose = require('mongoose')
const connectDB = (url) => {
return mongoose.connect(url, {
useNewUrlParser: true,
useCreateIndex: true,
useFindAndModify: false,
useUnifiedTopology: true,
})
}
module.exports = connectDB
Products model:
const mongoose = require('mongoose')
const productSchema = new mongoose.Schema({
name: {
type: String,
required: [true, 'products name must be provided']
},
price: {
type: Number,
required: [true, 'products price must be provided']
},
featured: {
type:Boolean,
default: false
},
rating: {
type: Number,
required: 4.5
},
createdAt: {
type: Date,
default: Date.now()
},
company:{
type: String,
enum:{
values: ['ikea', 'liddy', 'caressa', 'marcos'],
message: '{VALUE} is not supported'
}
// enum: ['ikea', 'liddy', 'caressa', 'marcos']
}
})
module.exports = mongoose.model('Product',productSchema)
The issue was in rating section of Products model
rating: {
type: Number,
required: 4.5
}
The correct format will be,
rating: {
type: Number,
default: 4.5
}
Which makes it an invalid model and therefore no function exists for an invalid model.
I created a Blog and for its slug, I install slugify and require it.
I'm trying to save a new blog post in MongoDB with mongoose, but I am getting this error: slug: ValidatorError: Path slug is required.
I validate slugify from the tutorial from Web Dev Simplified Youtube Channel but it is not working.
Here is the code :
// getting-started.js
const mongoose = require("mongoose");
const slugify = require("slugify");
main().catch((err) => console.log(err));
async function main() {
await mongoose.connect(process.env.ATLAS);
}
// Schema
const blogSchema = new mongoose.Schema({
title: {
type: String,
required: true,
unique: true,
},
description: {
type: String,
required: true,
},
slug: {
type: String,
required: true,
unique: true,
},
});
blogSchema.pre("validate", (next) => {
if (this.title) {
this.slug = slugify(this.title, { lower: true, strict: true });
}
next();
});
// Model
const Blog = mongoose.model("Blog", blogSchema);
Your code is correct, replace the arrow function with the regular function because "this" doesn't work with arrow functions and remove required: true from slug field.
blogSchema.pre("validate", function (next) {
if (this.title) {
this.slug = slugify(this.title, { lower: true, strict: true });
}
next();
});
I have created a rest API using NodeJS, Express, and MongoDB. I can successfully create data and view them in the database using MongoDB Compass but can't get single data using Id generated. Whenever I try it gives me a 404 error.
Here is my code:
bootcamps.js (controller)
const Bootcamp = require('../models/Bootcamp')
exports.getBootcamps = async (req, res, next) =>
{
try {
const bootcamps = await Bootcamp.find()
res.status(200).json({success: true, count: bootcamps.length, data: bootcamps})
} catch (error) {
res.status(400).json({success: false})
}
}
exports.getBootcamp = async (req, res, next) =>
{
try {
const bootcamp = await Bootcamp.findById({_id: req.params.id})
if (!bootcamp)
{
return res.status(400).json({success: false})
}
res.status(200).json({success: true, data: bootcamp})
} catch (error) {
res.status(400).json({success: false})
}
}
exports.createBootcamps = async (req, res, next) =>
{
try
{
const bootcamp = await Bootcamp.create(req.body)
res.status(201).json({
success: true,
data: bootcamp,
msg: 'Bootcamp created'
})
} catch (error)
{
console.log(error)
res.status(400).json({success: false})
}
}
exports.updateBootcamp = async (req, res, next) =>
{
try {
const bootcamp = await Bootcamp.findByIdAndUpdate(req.params.id, req.body, {
new: true,
runValidators: true
});
if (!bootcamp)
{
return res.statuc(400).json({success: false})
}
res.status(200).json({ success: true, data: bootcamp })
} catch (error) {
return res.statuc(400).json({success: false})
}
}
exports.deleteBootcamp = async (req, res, next) =>
{
try {
const bootcamp = await Bootcamp.findByIdAndDelete(req.params.id);
if (!bootcamp)
{
return res.statuc(400).json({success: false})
}
res.status(200).json({ success: true, data: {} })
} catch (error) {
return res.statuc(400).json({success: false})
}
}
Bootcamp.js (model)
const mongoose = require('mongoose')
const BootcampSchema = new mongoose.Schema({
name: {
type: String,
required: [true, 'Please add a name'],
unique: true,
trim: true,
maxlength: [50, 'Name can not be more than 50 characters']
},
slug: String,
description: {
type: String,
required: [true, 'Please add a description'],
maxlength: [500, 'Name can not be more than 50 characters']
},
website: {
type: String,
match: [
/https?:\/\/(www\.)?[-a-zA-Z0-9#:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()#:%_\+.~#?&//=]*)/,
"Please use a valid URL with HTTP or HTTPS"
]
},
phone: {
type: String,
maxlength: [20, 'Phone number can not be longer than 20 characters']
},
email: {
type: String,
match: [
/^\w+([\.-]?\w+)+#\w+([\.:]?\w+)+(\.[a-zA-Z0-9]{2,3})+$/,
'Please add a valid email address'
]
},
address: {
type: String,
required: [true, 'Please add an address']
},
location: {
type: {
type: String,
enum: ['Point'],
required: false
},
coordinates: {
type: [Number],
required: false,
index: '2dsphere'
}
},
formattedAddress: String,
street: String,
city: String,
state: String,
zipcode: String,
country: String,
careers: {
type: [String],
required: true,
enum: [
'Web Development',
'Mobile Development',
'UI/UX',
'Data Science',
'Business',
'Other'
]
},
averageRating: {
type: Number,
min: [1, 'Rating must be at least 1'],
max: [10, 'Rating can not be more than 10']
},
averageCost: Number,
photo: {
type: String,
default: 'no-photo.jpg'
},
housing: {
type: Boolean,
default: false
},
jobAssistance: {
type: Boolean,
default: false
},
jobGuarantee: {
type: Boolean,
default: false
},
acceptGi: {
type: Boolean,
default: false
},
createdAt: {
type: Date,
default: Date.now
}
});
module.exports = mongoose.model('Bootcamp', BootcampSchema)
bootcamps.js (routes)
const express = require('express')
const { getBootcamp, getBootcamps, createBootcamps, updateBootcamp, deleteBootcamp } = require('../controllers/bootcamps')
const router = express.Router()
router.route('/').get(getBootcamps).post(createBootcamps)
router.route(':id').put(updateBootcamp).delete(deleteBootcamp).get(getBootcamp)
module.exports = router
index.js (entry file)
const express = require('express')
const dotenv = require('dotenv')
const morgan = require('morgan')
const connectDB = require('./config/db')
const colors = require('colors')
dotenv.config({ path: './config/config.env' })
connectDB()
const bootcamps = require('./routes/bootcamps')
const app = express();
app.use(express.json())
if (process.env.NODE_ENV === 'development')
{
app.use(morgan('dev'))
}
app.use('/api/v1/bootcamps', bootcamps)
const PORT = process.env.PORT || 5000
const server = app.listen(PORT, console.log(`Server is running in
${process.env.NODE_ENV} mode on port ${PORT}`.yellow.bold))
process.on(`unhandledRejection`, (err, promise) =>
{
console.log(`Error: ${err.message}`.red)
server.close(() => process.exit(1))
})
Found the error!
I forgot to add the '/' on the single route
Before:
router.route(':id').put(updateBootcamp).delete(deleteBootcamp).get(getBootcamp)
After:
router.route('/:id').put(updateBootcamp).delete(deleteBootcamp).get(getBootcamp)
Surprisingly the console and postman result didn't complain and point that out!
All my other routes are working fine but when i try to fetch employees from db it doesn't work, i tried different approach to fetch my employees i.e. using app.get method in app.js and it worked, but when i try to use it with controllers and routes it doesn't even hit the route! please help! thankyou!
app.js
const express = require('express')
const app = express();
const appUserRoute = require('./routes/appuserRoute')
const employeeRoute = require('./routes/employeeRoute')
require('./db/mongoose')
app.use(express.json())
if(process.env.NODE_ENV!=="production"){
app.use(morgan('dev'))
}
app.use('/appusers',appUserRoute)
app.use('/appusers/employees',employeeRoute)
//start server
app.listen(PORT,
console.log(`Server running in ${process.env.NODE_ENV } mode on port ${PORT}`.green)
)
employeeRoute.js
const express = require('express')
const router = express.Router();
const {getEmployees, getEmployee, createEmployee, updateEmployee, deleteEmployee } = require('../controllers/employeeController')
router
.route('/')
.get(getEmployees)
.post(createEmployee)
router
.route('/:id')
.get(getEmployee)
.patch(updateEmployee)
.delete(deleteEmployee)
module.exports = router
employeeController.js
const Employee = require('../Models/employee')
exports.getEmployees = async (req, res) => {
try {
const employees = await Employee.find({})
if(!employees){
res.status(404).json({
message:'Not Data Found!'
})
}
res.status(200).json({
message:'Data Found!',
data:employees
})
} catch (e) {
res.status(500).send()
}
}
mongoose.js
const mongoose = require('mongoose')
mongoose.connect('mongodb://127.0.0.1:27017/MagicInventory-api', {
useNewUrlParser: true,
useCreateIndex: true,
useFindAndModify: false,
useUnifiedTopology: true
}).then(() => console.log("Connected".green))
.catch(err => console.log(err.red));
employee model
const mongoose = require('mongoose');
var validator = require('validator');
const employeeSchema = new mongoose.Schema({
firstName: {
type: String,
required: [true, 'please specify First Name'],
trim: true,
maxlength: [20, 'FirstName cannot be more than 20 characters!']
},
lastName: {
type: String,
trim: true,
// maxlength: [20, 'lastName cannot be more than 20 characters!']
},
email: {
type: String,
trim: true,
lowercase: true,
// unique: true,
// required: [true,'Email address is required'],
// validate: {
// validator: validator.isEmail,
// message: 'invalid email',
// }
},
maritalStatus: {
type: String,
// required:[true, 'Choose the Gender']
},
dateOfBirth: {
type: Date,
// required: [true, 'Date of Birth is required!']
},
profile: {
type: String,
lowercase: true
},
contactDetails: {
adressLine1: {
type: String
},
adressLine2: {
type: String
},
city: {
type: String
},
state: {
type: String
},
zipCode: {
type: Number
},
country: {
type: String
},
contact: {
type: Number,
match: [
/^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$/,
'Phone number is not valid!'
]
},
},
bankDetails:{
bankName:{
type:String,
},
accountNumber:{
type:Number
},
accountName:{
type:String
},
ifscCode:{
type:String
}
},
dateOfJoining:{
type: Date,
},
createdAt: {
type: Date,
default: Date.now
},
});
module.exports = mongoose.model('Employee', employeeSchema)
The problem is solved! I made a mistake while writing routes!
the actual route should be :- app.use('/employees',employeeRoute);
I want to export two schemas in my model js file and I want use in router js file. I have tried this code below.
This is my certification.js file(models)
const mongoose = require('mongoose');
const Schema = mongoose.schema;
const requestCertificationSchema = mongoose.Schema({
userid: { type: String, require: true },
certName: { type: String, require: true },
certType: { type: String, require: true },
examName: { type: String, require: true },
examYear: { type: String, require: true },
examIndex: { type: String, require: true },
reqDate: {type: String, require: true},
state: { type: String, require: true}
});
const requestCertification = mongoose.model("requestCertification", requestCertificationSchema);
module.exports.saveRequest = function (newRequestCertification, callback) {
newRequestCertification.save(callback);
};
const requestStudentstatusSchema = mongoose.Schema({
studentName: { type: String, require: true },
admissionNum: { type: String, require: true },
dateofAdmission: { type: String, require: true },
currentStatus: { type: String, require: true },
description: { type: String, require: true },
});
const requestStudentstatus= mongoose.model("requestStudentstatus", requestStudentstatusSchema);
module.exports = {
requestCertification: requestCertification,
requestStudentstatus: requestStudentstatus
}
This is my certification.js file(routes)
const router = express.Router();
const Certification = require('../models/certification');
const config = require('../config/database');
router.post("/requestCert", function (req, res) {
const newRequest = new requestCertification({
userid: req.body.userid,
certName: req.body.certName,
certType: req.body.certType,
examName: req.body.examName,
examYear: req.body.examYear,
examIndex: req.body.examIndex,
reqDate:req.body.reqDate,
state: req.body.state
});
console.log(newRequest);
Certification.requestCertification.saveRequest(newRequest, function (err, request) {
if (err) {
res.json({ state: false, msg: "Data inserting Unsuccessfull..!" });
}
if (request) {
res.json({ state: true, msg: "Data inserted Successfully..!" });
}
});
});
When I call this url i have show this error! .
ReferenceError: requestCertification is not defined
Change this code to this one in routes/certification.js
const router = express.Router();
const {requestCertification} = require('../models/certification');
const {requestStudentstatus} = require('../models/certification');
const config = require('../config/database');
router.post("/requestCert", function (req, res) {
const newRequest = new requestCertification({
userid: req.body.userid,
certName: req.body.certName,
certType: req.body.certType,
examName: req.body.examName,
examYear: req.body.examYear,
examIndex: req.body.examIndex,
reqDate:req.body.reqDate,
state: req.body.state
});
// console.log(newRequest);
newRequest
.save()
.then(result => {
console.log(result)
res.json({ state: true, msg: "Data inserted Successfully..!" });
})
.catch(error => {
console.log(error)
res.json({ state: false, msg: "Data inserting Unsuccessfull..!" });
})
});
and delete the saveRequest() function in models/certification.js