I am simply trying to update the content according to the id, but whichever id I am using, it updates only the first id by overriding it.
The flow goes as routes => controller => repository
Following is the code:
Routes =>
router.post("/:pageId/content", async (req, res, next) => {
try {
const pageId = req.params;
const pageContent = req.body;
if (!pageId || !pageContent) {
throw {
statusCode: 200,
customMessage: "All parameters are required"
};
}
const result: any = await webpageController.createContent(
pageId,
pageContent
);
if (result.isError) {
throw result.error;
}
res.status(200).json(result.data);
} catch (error) {
next(error);
}
});
Controller =>
const createContent = async (pageId: any, pageContent: any) => {
try {
// calls repository to create content
const result = await webpageRepository.createContent(pageId, pageContent);
// if result is not success, throw error
if (!result.success) {
throw {
statusCode: 400,
customMessage: "Unable to create web page content"
};
}
return {
isError: false,
data: result.data
};
Repository =>
export const createContent = async (pageId: any, content: any) => {
try {
const result = await webpage.findOneAndUpdate(pageId, { content });
return {
data: result,
success: true
};
} catch (error) {
logger.error(
`at:"repositories/webpage/createContent" => ${JSON.stringify(error)}`
);
return {
success: false
};
}
};
Here it can be seen that the id I have used in the route and the id getting updated is different.
What am I doing wrong here?
Following is the schema:
const mongoose = require('mongoose');
const { Schema } = mongoose;
const webpage = new mongoose.Schema(
{
name: {
type: String,
required: true,
trim: true,
maxlength: 25,
},
slug: {
type: String,
// required: true,
},
url: {
type: String,
required: true,
unique: true
},
content: Object,
},
{
timestamps: true,
},
);
export default mongoose.model('webpages', webpage);
I think you should use a dictionary as the parameter.
const result = await webpage.findOneAndUpdate({_id:pageId.pageId}, {content});
You can check on this documentation about how to use the "findOneAndUpdate" https://mongoosejs.com/docs/tutorials/findoneandupdate.html#getting-started
This worked for me
const result = await webpage.findOneAndUpdate( {_id:pageId.pageId} , { content });
Related
can this be done with fetch api which method should i use post or put? please reply.. can someone please give me the complete api to push orderSchema as a subdocument in userSchema i have scrolled tons and tons of links still i am not able to find any answer too this
this is the schema i am using in mongo db.
import mongoose from 'mongoose'
const orderSchema = new mongoose.Schema({
rsph: { type: Number },
rcyl: { type: Number },
raxis: { type: Number },
lsph: { type: Number },
lcyl: { type: Number },
laxis: { type: Number },
add: { type: Number },
frame: { type: String },
lens: { type: String }
}, {
timestamps: true
});
const userSchema = new mongoose.Schema({
name: { type: String, required: true },
phone: { type: Number, required: true },
address: { type: String, required: true },
orders: [orderSchema]
}, {
timestamps: true
});
export default mongoose.models.User || mongoose.model('User', userSchema)
I am using this api to save userschema and this is working.
import initDB from '../../helper/initDB';
import User from '../../models/addUser';
initDB()
export default async (req, res) => {
(req.method)
{
"POST"
await handler(req, res)
}
}
const handler = async (req, res) => {
if (req.method == 'POST') {
console.log(req.body)
const { name,phone,address } = req.body
let u = new User( {name,phone,address } )
await u.save()
res.status(200).json({ success: "success" })
}
else {
res.status(400).json({ error: "this method is not required" })
}
}
I am using this api to save this data as a subdocument but this api is not working what changes should i make?
import initDB from '../../../helper/initDB';
import User from '../../../models/addUser';
initDB()
export default async (req, res) => {
(req.method)
{
"POST"
await handler(req, res)
}
}
const handler = async (req, res) => {
if (req.method == 'POST') {
console.log(req.body)
const { uid } = req.query
const user = await User.findOne({ _id: uid })
const { rsph, rcyl, raxis, lsph, lcyl, laxis, add, frame, lens } = req.body
const order = ({ rsph, rcyl, raxis, lsph, lcyl, laxis, add, frame, lens });
user.orders.push(order);
await user.save()
res.status(200).json({ success: "success" })
}
else {
res.status(400).json({ error: "this method is not required" })
}
}
please reply...
Remove bracket () from the below line.
const order = ({ rsph, rcyl, raxis, lsph, lcyl, laxis, add, frame, lens });
only pass the object, as
const order = { rsph, rcyl, raxis, lsph, lcyl, laxis, add, frame, lens };
The final should be as:
const handler = async (req, res) => {
if (req.method == 'POST') {
console.log(req.body)
const { uid } = req.query
const user = await User.findOne({ _id: uid })
const { rsph, rcyl, raxis, lsph, lcyl, laxis, add, frame, lens } = req.body
const order = { rsph, rcyl, raxis, lsph, lcyl, laxis, add, frame, lens };
user.orders.push(order);
await user.save()
res.status(200).json({ success: "success" })
}
else {
res.status(400).json({ error: "this method is not required" })
}
}
this get route is giving no error in post-man but doing the same with frontend giving error in node console:
ObjectParameterError: Parameter "filter" to find() must be an object, got search
although response are fetched.
get controller
const Recent = require("../models/recent");
const getRecentByName = async (req, res, next) => {
const name = req.params.name;
let regex = new RegExp(name, "i");
let players;
try {
players = await Recent.find({ name: { $regex: regex } });
} catch (err) {
return next(err);
}
if (!players) {
return next("no player found");
}
// console.log(players);
res.json({ players });
};
exports.getRecentByName = getRecentByName;
fetching from frontend:
const searchRecords = async () => {
const data = await sendRequest(
"http://localhost:5000/api/player/recent/search/" + search,
"GET"
);
setRecord(data.players);
};
Recent:(mongoose Schema):
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const recentSchema = new Schema({
name: { type: String, required: true },
recent: [
{
team1: { type: String },
team2: { type: String },
points: { type: Number, required: true },
date: { type: Date },
},
],
});
module.exports = mongoose.model("Recent", recentSchema);
I think the problem is from the front and in the URL
you should use
http://localhost:5000/api/player/recent/search/${search}
I have a middleware that uses express-validator to validate request,
const { validationResult } = require("express-validator");
module.exports = {
validate: (req, res, next) => {
const raw_errors = validationResult(req);
if (raw_errors.isEmpty()) {
return next()
}
const errors = raw_errors.errors.map((err) => ({ message: err.msg }));
return res.status(422).json({ status: "error", errors });
},
}
I use it on the route like so:
const { validate } = require('../middlewares/validation')
routes.post('/', validate, (req, res) => {
postService.add(req.body.name, req.body.description).then(post => {
res.status(201).json({ message: 'post added', data: post })
}).catch(error => {
handleError(error, res)
})
})
But when i try to make an API call with an empty request body, it does not return any errors.
Here is my model
const mongoose = require('mongoose');
const PostSchema = mongoose.Schema( {
name: {
type: String,
required: [true, 'Please provide a name'],
},
description: {
type: String,
required: [true, 'Please provide a description'],
}
},
{timestamps: true}
);
module.exports = mongoose.model('Post', PostSchema);
Here is my postService
module.exports = {
//adds a post
add : async (name, description) => {
try{
const tab = { name, description }
return postModel.create(tab)
}
catch(err){
throw new ErrorHandler(500, "Unable to add post at this time. Please try again later.")
}
},
}
When I log raw_errors from the middleware, I get - Result { formatter: [Function: formatter], errors: [] }
Please what might be wrong?
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 have created a Mongo DB schema with Mongoose in Express.js and I am building the REST API. However when I try to update existing records the values that I do not update from the schema automatically become null. I understand why this happens just not sure exactly how it should be coded.
This is the route:
router.patch("/:projectId", async (req, res) => {
try {
const updatedProject = await Project.updateOne(
{ _id: req.params.projectId },
{
$set: {
title: req.body.title,
project_alias: req.body.project_alias,
description: req.body.description
}
}
);
res.json(updatedProject);
} catch (err) {
res.json({ message: err });
}
});
also here is the schema:
const ProjectsSchema = mongoose.Schema({
title: {
type: String,
required: true,
unique: true
},
project_alias: {
type: String,
unique: true,
required: true
},
description: String,
allowed_hours: Number,
hours_recorded: {
type: Number,
default: 0
},
date_added: {
type: Date,
default: Date.now
}
});
My problem is that when I want to update just the title:
{
"title" : "Title Updated33"
}
description and alias become null. Should I implement a check?
Just use req.body for the update object like this:
router.patch("/:projectId", async (req, res) => {
try {
const updatedProject = await Project.updateOne(
{ _id: req.params.projectId },
req.body
);
res.json(updatedProject);
} catch (err) {
res.json({ message: err });
}
});
Or even better, create a helper function like this so that we can exclude the fields in the body that doesn't exist in the model:
const filterObj = (obj, ...allowedFields) => {
const newObj = {};
Object.keys(obj).forEach(el => {
if (allowedFields.includes(el)) newObj[el] = obj[el];
});
return newObj;
};
router.patch("/:projectId", async (req, res) => {
const filteredBody = filterObj(
req.body,
"title",
"project_alias",
"description",
"allowed_hours",
"hours_recorded"
);
try {
const updatedProject = await Project.updateOne(
{ _id: req.params.projectId },
filteredBody
);
res.json(updatedProject);
} catch (err) {
res.json({ message: err });
}
});