I am trying to add query params that allow the api user to have the option to sort by descending order based on the title field and to limit the the amount items the query returns. But when I call the endpoint it still just returns the data unsorted and without the limit applied to it.
getCourses = async (req, res) => {
try {
const limit = req.query.limit | 20;
if (req.query.desc === "true") {
const data = await courseModel.find().sort({ title: -1 }).limit(limit);
return res.json(data);
} else {
const data = await courseModel.find().aggregate({ $limit: limit });
return res.json(data);
}
} catch (error) {
return res.status(500).json({ message: error.message });
}
};
const courseSchema = mongoose.Schema({
title: {
type: String,
required: true
},
description: {
type: String,
required: true
},
category: {
type: String,
required: true
},
price: {
type: Number,
required: true
},
length: {
type: Number,
required: true
}
})
const CourseMessge = mongoose.model('CourseMessage', courseSchema);
module.exports = CourseMessge
This is how i am calling the end point:
localhost:3000/api/courses?desc=true&limit=10
You should use the || operator for specifying a default value for the limit.
Also, try to cast the desc parameter to a string:
getCourses = async (req, res) => {
try {
const limit = req.query.limit || 20;
if (req.query.desc.toString() === 'true') {
const data = await courseModel.find().sort({ title: -1 }).limit(limit);
return res.json(data);
} else {
const data = await courseModel.find().limit(limit);
return res.json(data);
}
} catch (error) {
return res.status(500).json({ message: error.message });
}
};
Related
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 });
Hello this is the first time I post a question.
So basically i'm build an API to manage car(Im doing this as a training for better building API). My connection to the D is made using a singleton which is called once by server and the mongo promises are global(and it works fine for now)
I have my model:
import mongoose, {Schema} from "mongoose";
import mongooseUniqueValidator from "mongoose-unique-validator";
class Voiture{
initSchema(){
const schema = new Schema({
Marque:{
type: String,
require:true,
},
Modele:{
type: String,
require:true,
},
Année:{
type: Number,
require:true,
},
Energie:{
type: String,
require:true,
},
Boite_De_Vitesse:{
type: String,
require:true,
},
couleur_exterieure:{
type: String,
require:true,
},
couleur_intérieur:{
type: String,
},
nombre_De_Portes:{
type: Number,
},
nombre_De_Places:{
type: Number,
},
Prix:{
type: Number,
},
Etat:{
type: String,
require: true,
},
Kilométrage:{
type: Number,
},
prix_location:{
type: Number,
require:true,
}
},{timestamp: true});
schema.plugin(mongooseUniqueValidator);
mongoose.model("voitures", schema);
}
getInstance() {
this.initSchema();
return mongoose.model("voitures");
}
}
export default Voiture;
and I also have services and controllers attached to them
I can get all the documents in the mongoDB Database but I can't create Documents
Here is my service
import voiture from "../models/Voiture"
import mongoose from "mongoose"
class VoitureService{
constructor(){
this.model = new voiture().getInstance();
this.getAll = this.getAll.bind(this);
this.insert = this.insert.bind(this);
}
/**
* GET All voiture
*/
async getAll(query){
let {skip, limit} = query;
skip = skip ? Number : 0;
limit = limit ? Number : 10;
delete query.skip;
delete query.limit;
if(query._id){
try {
query._id = new mongoose.mongo.ObjetId(uery._id);
} catch (error) {
console.log("not able to generate mongoose id with content", query._id);
}
}
try {
let items = await this.model
.find(query)
.skip(skip)
.limit(limit)
let total = await this.model.countDocuments();
return {
error: false,
statusCode: 200,
data: items,
total
};
} catch (errors) {
return {
error: true,
statusCode: 500,
errors
};
}
}
/**
* Insert a car in the Database
*/
async insert(data){
console.log("line 60");
try {
console.log("line 62");
let item = await this.model.create(data, function (err) {
console.log("line 64");
if (err) return handleError(err);
// saved!
console.log("line 67");
});
if (item){
console.log("line 70");
return {
error: false,
item
};
}
} catch (error) {
console.log("error", error);
return {
error: true,
statusCode: 500,
message: error.message || "Not able to create item",
errors: error.errors
};
}
}
}
And this my controller
async addCar(req, res){
let response = await this.service.insert(req.body)
if (res.error) return res.status(res.statusCode).send(response);
return res.status(201).send(response);
}
I tried to log the Item but it gives me undefined
Thanks to all of you !
Salayna
You can Follow this code
// At Frist, You import **Voiture** Model Then use the model
async insert(data){
console.log("line 60");
try {
console.log("line 62");
let item = await Voiture.create(data, function (err) {
console.log("line 64");
if (err) return handleError(err);
// saved!
console.log("line 67");
});
if (item){
console.log("line 70");
return {
error: false,
item
};
}
} catch (error) {
console.log("error", error);
return {
error: true,
statusCode: 500,
message: error.message || "Not able to create item",
errors: error.errors
};
}
}
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 });
}
});
I want to find an existing id object when I post a bill, but I don't know how find it to save the bill. I want it works from back end and front end.
This is my bill model:
const mongoose = require("mongoose");
const { Schema } = mongoose;
const billSchema = new Schema({
number: Number,
date: { type: Date, default: Date.now() },
type: String,
local: String,
client: {
type: mongoose.Schema.Types.ObjectId,
ref: "clients"
},
provider: {
type: mongoose.Schema.Types.ObjectId,
ref: "providers"
},
detail: [
{
quantity: Number,
product: {
code: Number,
name: String,
price: Number
},
undertotal: Number
}
],
total: Number
});
module.exports = mongoose.model("bills", billSchema);
And this is my post service:
app.post("/api/bills", async (req, res) => {
const { number, type, local, detail, total } = req.body;
let existingClient = await Client.findById(Client._id);
if (!existingClient) {
return res.status(404).json({
message: "not found client"
});
}
let existingProvider = await Provider.findById(Provider._id);
if (!existingProvider) {
return res.status(404).json({
message: "not found provider"
});
}
if (
!existingClient._id ||
(existingClient._id &&
mongoose.Types.ObjectId() ===
(await Client.findById(existingClient._id).select("_id")))
) {
const clientId = mongoose.Types.ObjectId();
this.existingClient._id = clientId;
}
if (
!existingProvider._id ||
(existingProvider._id &&
mongoose.Types.ObjectId() ===
(await Provider.findById(existingProvider._id).select("_id")))
) {
const providerId = mongoose.Types.ObjectId();
this.existingProvider._id = providerId;
}
const bill = new Bill({
number,
date: new Date(),
type,
local,
client: clientId,
provider: providerId,
detail,
total
});
try {
let newBill = await bill.save();
res.status(201).send(newBill);
} catch (err) {
if (err.name === "MongoError") {
res.status(409).send(err.message);
}
console.log(err);
res.status(500).send(err);
}
});
The expected output is bill saved with client and provider ids but real output is an error message saying "cannot read property _id of undefined"
What is wrong?
I have a problem with my MongoDB collection. If i try to replace field in my item it won't get saved. It logs new value correctly, but nothing in DB really changes. What's wrong here?
exports.update = function (req, res) {
const { entryid, userid } = req.params;
let field;
['stop', 'description'].forEach(item => req.query[item] ? field = item : -1);
db.TimeEntry.findById(entryid).then(function (entry) {
(req.query[field] === undefined) ? entry[field] = 'no value specified' : entry[field] = req.query[field];
console.log('v:', entry[field]);
entry.save(function (err) {
if (err) console.log(err);
db.TimeEntry.find({ userId: userid })
.then(foundEntries => res.status(200).json(foundEntries));
});
}).catch(err => console.log(err));
}
Schema:
const mongoose = require('mongoose');
const TimeEntrySchema = new mongoose.Schema({
start: {
type: mongoose.Schema.Types.Mixed,
default: Date.now,
required: true
},
stop: mongoose.Schema.Types.Mixed,
description: String,
project: String,
billable: Boolean,
userId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
required: true
}
}, { timestamps: true })
TimeEntrySchema.pre('remove', function (next) {
User.findById(this.userId).then(user => {
user.entries.remove(this.id);
user.save().then(function (e) {
next();
}).catch(err => console.log(err));
})
});
const TimeEntry = mongoose.model('TimeEntry', TimeEntrySchema);
module.exports = TimeEntry;
Edit: Modified this way, still no effect.
` entry[field] = (!req.query[field]) ? 'TESTINGTESTING' : req.query[field];
entry.markModified('description');
console.log('v:', entry[field]);
entry.save().then(function (err) {`
Final edit: Ok so this is the final solution.
exports.update = function (req, res) {
const { entryid, userid } = req.params;
let field;
['stop', 'description'].forEach(item => req.query[item] ? field = item : -1);
db.TimeEntry.update({ _id: entryid }, {
$set: {
description: req.query[field] || 'no value specified'
}
}).then(function () {
db.TimeEntry.find({ userId: userid })
.then((foundEntries) => res.status(200).json(foundEntries))
}).catch(err => console.log(err));
}
Try using .update:
return db.TimeEntry.update({ _id: entryid }, {
$set: {
[field]: req.query[field] || 'no value specified'
}
}
}).then(() => db.TimeEntry.find({ _id: entryid }))
.then((resultEntries) => res.status(200).json(foundEntries))
Have you tried this: entry.save().exec(callbackFN);
instead of entry.save(callbackFN); ?