Deleting Order Items from Orders - javascript

I have the following JSON stored in mongodb
[
{
"orderItems": [
"606808d2d7351b0c52d38634",
"606808d2d7351b0c52d38635"
],
"status": "Pending",
"_id": "606808d2d7351b0c52d38636",
"shippingAddress1": "Flowers Street , 45",
"shippingAddress2": "1-B",
"city": "Thessaloniki",
"zip": "00000",
"country": "Greece",
"phone": "+00302410551416",
"user": {
"_id": "6062d46da91a58067da5dfc2",
"name": "Vasilis",
"id": "6062d46da91a58067da5dfc2"
},
"dateOrdered": "2021-04-03T06:18:58.879Z",
"__v": 0,
"id": "606808d2d7351b0c52d38636"
}
]
I can delete the order, no problem with that
router.delete('/:id', (req, res) => {
Order.findByIdAndRemove(req.params.id)
.then((order) => {
if(order) {
res.status(200).json({
success: true,
message: 'The order is deleted'
})
} else {
res.status(404).json({
success: false,
message: 'order not found'
})
}
}).catch((err) => {
return res.status(400).json({
success: false,
error: err
})
})
})
Now I want to change the above code, so as to delete the orderItems as well. how to do that?
Thanks,
Theo

You can use Model.deleteMany to delete the OrderItems (I'm guessing that's the model name) after deleting the Order document. And you don't have to call status(200) on the response object since it's automatically set when calling res.json.
router.delete('/:id', async (req, res) => {
try {
const order = await Order.findByIdAndRemove(req.params.id)
if (!order) {
return res.status(404).json({
success: false,
message: 'Order not found',
})
}
await OrderItem.deleteMany({ _id: { $in: order.orderItems } })
res.json({
success: true,
message: 'Order deleted',
})
} catch (err) {
return res.status(500).json({
success: false,
error: err,
})
}
})

Related

how to query in NodeJS and Mongoose where a field equal or not equal to a value (exclude a field)

I am creating my rest api. I am looking for a way that I am able to find data by field which I am currently able to do. However I would also like to be able to add feature where I can get data where field does not exist.
Example:
Find all records that has a uuid
Find all records where title is not empty
Find all records where title equal "Test Message" but description not equal "bad"
recordRouter
.route("/templates")
.get((req, res, next) => {
Templates.find(req.query)
.then(
(record) => {
res.statusCode = 200;
res.setHeader("Content-Type", "application/json");
res.json(record);
},
(err) => res.status(400).json(err)
)
.catch((err) => res.status(400).json(err));
})
.post((req, res, next) => {
Templates.create(req.body)
.then(
(record) => {
res.statusCode = 200;
res.setHeader("Content-Type", "application/json");
res.json(record);
},
(err) => res.status(400).json(err)
)
.catch((err) => res.status(400).json(err));
})
database records
{
"_id": {
"$oid": "6149290b197615d32c515dab"
},
"instantMessage": false,
"isComplete": true,
"date": "2021-09-21",
"description": "This is a test messjage v4",
"owner": "wxTWH8zqSwaIXPAVsjZoRCkvjx73",
"remindTime": "1630203423",
"title": "Test Message",
"uuid": "0Easdf-1uasdf",
"createdAt": "2021-08-30T20:01:36.608Z",
"updatedAt": "2021-08-30T20:01:36.608Z",
"templateName": "my test template",
"_ref": 1632314979,
"__v": 0
},
{
"_id": {
"$oid": "614a2bf5560184026def253a"
},
"date": "2021-09-21",
"title": "Test Message",
"description": "BAD",
"remindTime": 1632254400,
"isComplete": true
}
1 uuid exists :
db.collection.find({
uuid: {
"$exists": true
}
})
https://mongoplayground.net/p/Yytnh__L2sS
2 title was not empty
db.collection.find({
title: {
"$ne": ""
}
})
https://mongoplayground.net/p/Hko_DKKgubu
3 description not BAD and title Test Message
db.collection.find({
description: {
"$ne": "BAD"
},
title: "Test Message"
})
https://mongoplayground.net/p/qhpkOpvcaeA
all of these in and
db.collection.find({
$and: [
{
description: {
"$ne": "BAD"
},
title: "Test Message"
},
{
title: {
$ne: ""
}
},
{
uuid: {
"$exists": true
}
}
]
})
https://mongoplayground.net/p/hodEeuoz17m

How to pass two requests in single API call with Node js - Cloudant

I'm trying to pass two search requests in single API call But here some times I am getting both requests results and some times getting only one request results.
Basically this is my JSON structure in cloudant db:
{
"_id": "123",
"name": "Naveen",
"hoby": "Cricket"
},
{
"_id": "234",
"name": "Varun",
"hoby": "chess"
},
{
"_id": "345",
"name": "Tarun",
"hoby": "Cricket"
},
{
"_id": "456",
"name": "pavan",
"hoby": "chess"
}
Here my requirement would be to get 'hoby' of Cricket 50 members and 'hoby' of Chess 50 members.
For that this is how I am trying currently:
doGet: function(request, response) {
var usersState = [];
var names = { "usersState": usersState, "message": "ok" };
if (!myDb) {
response.json({ "message": "Dataabase connection failed" });
return;
}
var queryForCricket = {
"selector": {
"hoby": "Cricket"
},
"fields": [
"_id",
"name",
"hoby"
],
"sort": [],
"limit": 50,
"skip": 0
};
var queryForChess = {
"selector": {
"hoby": "chess",
},
"fields": [
"_id",
"name",
"hoby"
],
"sort": [],
"limit": 50,
"skip": 0
};
async.parallel(
[
myDb.find(queryForCricket, function (err, body) {
if (!err) {
body.docs.forEach(function (doc) {
if (doc)
usersState.push(doc);
});
response.json(names);
}
}),
myDb.find(queryForChess, function (err, body) {
if (!err) {
body.docs.forEach(function (doc) {
if (doc)
usersState.push(doc);
});
}
})
], function (err, results) {
if (err) {
response.send({ "message": "Read operration failed" });
return;
}
});
}
I have written two queries and passing two through Async call but not getting results properly all the time. So is there any optimised way to handle query part and getting results.
The issue here is your final result depends on execution order of both callbacks of your async.parallel find functions. When the second find finishes first you'll get both results but when the first find finishes first you'll get only results of queryForCricked query.
To get both results you should collect them in the final callback function and use response.json there:
...
async.parallel(
[
myDb.find(queryForCricket, function (err, body) {
if (!err) {
body.docs.forEach(function (doc) {
if (doc)
usersState.push(doc);
});
}
}),
myDb.find(queryForChess, function (err, body) {
if (!err) {
body.docs.forEach(function (doc) {
if (doc)
usersState.push(doc);
});
}
})
], function (err, results) {
if (err) {
response.send({ "message": "Read operration failed" });
return;
}
response.json(names);
}
);
...
While collecting data in the shared usersState array is completely working approach it has flaws. For example, you cannot control the order in which your find data will be inserted. async.parallel gives a better way to collect the data from the functions it's running. You can use callback async.parallel inserts into each function to collect the data in the final callback:
async.parallel(
[
function (cb) { myDb.find(queryForCricket, cb); },
function (cb) { myDb.find(queryForChess, cb); },
], function (err, results) {
if (err) {
response.send({ "message": "Read operration failed" });
return;
}
// result is an array with data from queries: [crickets.body, chess.body]
results.forEach(function (body) {
body.docs.forEach(function (doc) {
if (doc) usersState.push(doc);
});
});
response.json(names);
}
);
...

Mongoose select specific fields from array

I'm trying to reduce my API data size to remove unwanted data. I have schema like this
const course = mongoose.Schema(
{
course_name: { type: String, require: true },
disabled: { type: String, required: true, default: false },
subject_ids: [
{
type: mongoose.Schema.ObjectId,
ref: 'subject',
require: true,
},
],
},
{ timestamps: true }
);
after applying the find query i have data like this
{
"disabled": "false",
"subject_ids": [
{
"disabled": "false",
"_id": "60b0bdd5cd7bd635ecf07cd5",
"subject_name": "CSS",
"createdAt": "2021-05-28T09:54:29.147Z",
"updatedAt": "2021-05-28T09:54:29.147Z",
"__v": 0
},
{
"disabled": "false",
"_id": "60b0bdd5cd7bd635ecf07cd7",
"subject_name": "Jquery",
"createdAt": "2021-05-28T09:54:29.147Z",
"updatedAt": "2021-05-28T09:54:29.147Z",
"__v": 0
}
],
"_id": "60b0e3f3012b2b272432e9f9",
"course_name": "Data Science",
"createdAt": "2021-05-28T12:37:07.103Z"
}
API
I have tried something like this. I already remove data from the outside array, but I don't know how I can remove it from the inside. I do lots of google search but I didn't get
router.get('/get-course/:status', async (req, res) => {
try {
const data = await COURSE.find({})
.populate('subject_ids')
.select({ updatedAt: 0, __v: 0 })
.exec();
res.json(data);
} catch (error) {
res.status(404).json({ err: 1, message: error.message, error });
}
});
I want data should be like this
{
"disabled": "false",
"subject_ids": [
{
"_id": "60b0bdd5cd7bd635ecf07cd5",
"subject_name": "CSS",
},
{
"_id": "60b0bdd5cd7bd635ecf07cd7",
"subject_name": "Jquery",
}
],
"_id": "60b0e3f3012b2b272432e9f9",
"course_name": "Data Science",
"createdAt": "2021-05-28T12:37:07.103Z"
}
How to get specific data from array
Try this
router.get('/get-course/:status', async (req, res) => {
try {
const data = await COURSE.find({})
.populate('subject_ids')
.select({
updatedAt: 0,
__v: 0,
subject_ids.disabled: 0,
subject_ids.createdAt: 0
subject_ids.updatedAt: 0
subject_ids.__v: 0
})
.exec();
res.json(data);
} catch (error) {
res.status(404).json({ err: 1, message: error.message, error });
}
});
Try this:
populate('subject_ids','subject_name').exec()
U can use
router.get('/get-course/:status', async (req, res) => {
try {
const data = await COURSE.find({})
.select("-subject_ids.disabled -subject_ids.createdAt -subject_ids.updatedAt -subject_ids.__v")
.exec()
res.json(data);
} catch (error) {
res.status(404).json({ err: 1, message: error.message, error });
}
});
The
.select("-parentArray.child")
excludes the child property of all elements in the Array.

How can I update value in object with node.js and sequelize

I would like to update values (missions.status and missions.success) in the object,
but I don't know how to approach it.
"missions": {
"missions": [
{
"week": 1,
"status": "",
"mission": "do something",
"success": ""
}
]
}
I tried to like this.
//success.js
router.put('/:id/result', async (req, res, next) => {
const status = req.body.missions.missions[0].status;
const success = req.body.missions.missions[0].success;
try {
const result = await models.User.findOne({
attribute: ['missions'],
where: {
id: req.params.id,
},
});
const data = {
result: result,
};
let originalData = data.result.dataValues.missions.missions[0];
let weekdata = { status: status, success: success };
let resultData = Object.assign(originalData, weekdata);
res.send({
data: resultData,
message: 'good status changed',
});
} catch (error) {
console.log(error);
res.sendStatus(400);
}
});
It is req.body and response, looks like it works, but doesn't update in databases. I don't know how to save that.
//req.body
{
"missions": {
"missions":[
{
"status": "no",
"success":"success"
}
]
}
}
// res.send
{
"data": {
"week": 1,
"status": "no",
"mission": "do something",
"success": "success"
},
"message": "good status changed"
}
You didn't call update for your model so that's why you'll get no changes in a DB.
Try this:
await models.User.update(weekdata, {
where: {
id: req.params.id,
},
});

Trying to seed DB with Mongoose. Looping over JSON while adding relational data

I'm trying to seed a DB for a React school assignment and this code here creates the two collections from the JSON objects, but the relation I'm trying to achieve in the loop isn't working.
When I use postman to add a vacation though after starting the server, the relation works. Console logging in the create promise only writes the first object to the terminal. I was using a forEach before I saw the suggestion to use async.
Seed.js
const mongoose = require("mongoose");
const db = require("../models");
var async = require('async');
mongoose.connect(process.env.MONGODB_URI || "mongodb://localhost/app", { useUnifiedTopology: true, useNewUrlParser: true, useFindAndModify: false });
const userSeed = [
{
name: "Bill",
email: "bill#bill.com",
password: "waewfeawf",
vacations: []
}
];
const vacaSeed = [
{
"email": "bill#bill.com",
"name": "Vaawdawddver!",
"startDate": "2019-12-2",
"endDate": "2019-12-6",
"location": "Alaska",
"activities": ["camping", "biking", "hiking", "fishing"]
},
{
"email": "bill#bill.com",
"name": "Future!",
"startDate": "2020-12-2",
"endDate": "2020-12-6",
"location": "Alaska",
"activities": ["camping", "biking", "hiking", "fishing"]
},
{
"email": "bill#bill.com",
"name": "Vaawdawddver1!",
"startDate": "2019-12-2",
"endDate": "2019-12-6",
"location": "Alaska",
"activities": ["camping", "biking", "hiking", "fishing"]
},
{
"email": "bill#bill.com",
"name": "Vaawdawddver2!",
"startDate": "2019-12-2",
"endDate": "2019-12-6",
"location": "Alaska",
"activities": ["camping", "biking", "hiking", "fishing"]
},
]
db.User
.deleteMany({})
.then(() => db.User.collection.insertMany(userSeed))
.then(data => {
console.log(data);
process.exit(0);
})
.catch(err => {
console.error(err);
process.exit(1);
});
db.Vacation
.deleteMany({})
.then(data => {
// console.log(data)
process.exit(0);
})
.catch(err => {
console.error(err);
process.exit(1);
});
async.each(vacaSeed, function (data, callback) {
db.Vacation
.create(data)
.then(dbModel => {
db.User.findOneAndUpdate({ email: data.email }, { $push: { vacations: dbModel._id } }, { new: true })
.catch(err => console.log(err));
})
})
Controller Code - working
create: function (req, res) {
db.Vacation
.create(req.body)
.then(dbModel => {
return db.User.findOneAndUpdate({ email: req.body.email }, { $push: { vacations: dbModel._id } }, { new: true }).then(dbUser => res.json(dbUser)).catch(err => res.status(422).json(err));
})
},
I ended up combining the two Vacation DB calls into one call while also closing the mongoose connection once it reaches the end of the JSON object.
db.Vacation
.deleteMany({})
.then(data => {
vacaSeed.forEach((item, idx, vacaSeed) => {
db.Vacation
.create(item)
.then(dbModel => {
db.User.findOneAndUpdate({ email: item.email }, { $push: { vacations: dbModel._id } }, { new: true }).then(data => {
if (idx + 1 === vacaSeed.length) {
mongoose.connection.close()
}
})
})
})
}).catch(err => {
console.log(err)
process.exit(1)
});

Categories

Resources