My updated data does not reflect in even it is status 200 - reactjs

I want to increase the score of a player by updating it. Here is the call.
const addPlayerScore = async (score, currentPlayer) => {
try {
const addScore = {
score: score,
};
const { data } = await fetchContext.authAxios.patch(
`/facilitator/add-score-player-team-one/${currentPlayer}`,
addScore
);
console.log(data.message);
} catch (error) {
const { data } = error.response;
console.log(data.message);
}
};
the currentPlayer takes the id of player. Which I passed into the params.
here is the request;
exports.addscoreplayerteamone = async (req, res) => {
try {
const { score } = req.body;
const existLive = await LiveMatch.findOneAndUpdate(
{
'teamOne.players._id': req.params.id,
},
{
$set: {
$inc: {
'teamOne.players.$.scores': score,
},
},
},
{ new: true }
);
const addPlayerScore = await existLive.save();
res
.status(200)
.send({ message: "Added the player's score", addPlayerScore });
} catch (error) {
console.log(error);
return res.status(400).json({
message: 'There was a problem adding a score',
});
}
};
here is the schema;
const mongoose = require('mongoose');
const liveSchema = new mongoose.Schema(
{
schedule: {
type: mongoose.Types.ObjectId,
required: true,
},
user: {
type: mongoose.Types.ObjectId,
required: true,
},
teamOne: {
teamName: {
type: String,
required: true,
trim: true,
max: 50,
},
players: [
{
name: {
type: String,
required: true,
trim: true,
max: 50,
},
jerseyNumber: {
type: String,
required: true,
trim: true,
},
scores: {
type: Number,
default: 0,
trim: true,
},
fouls: {
type: Number,
trim: true,
},
},
],
score: {
type: Number,
trim: true,
default: 0,
},
},
teamTwo: {
teamName: {
type: String,
required: true,
trim: true,
max: 50,
},
players: [
{
name: {
type: String,
required: true,
trim: true,
max: 50,
},
jerseyNumber: {
type: String,
required: true,
trim: true,
},
scores: {
type: Number,
default: 0,
trim: true,
},
fouls: {
type: Number,
trim: true,
},
},
],
score: {
type: Number,
trim: true,
default: 0,
},
},
gameEvent: {
type: String,
required: true,
enum: ['basketball', 'volleyball', 'soccer'],
},
winner: {
type: String,
trim: true,
},
loser: {
type: String,
trim: true,
},
},
{ timestamps: true }
);
module.exports = mongoose.model('live-match', liveSchema);
it returns status 200 but it does not increments the score of the player in the database nor being reflected in the frontend.

Try this:
const existLive = await LiveMatch.findOneAndUpdate(
{
'teamOne.players._id': req.params.id,
},
{
$inc: { 'teamOne.players.scores': score }
},
{
new: true
}
);

Related

Mongoose updating subdocument array

I want to update rooms subdocument which is in Property document, but I get this error:
MongoServerError: Updating the path 'rooms.$.updatedAt' would create a
conflict at 'rooms.$'
Error which i got in postman:
{
"ok": 0,
"code": 40,
"codeName": "ConflictingUpdateOperators",
"$clusterTime": {
"clusterTime": {
"$timestamp": "7137698220989218823"
},
"signature": {
"hash": "34spx6E0zZFa5bVYFSL2JyjFszQ=",
"keyId": {
"low": 2,
"high": 1646669662,
"unsigned": false
}
}
},
"operationTime": {
"$timestamp": "7137698220989218823"
}
}
My property model:
import { IReview, ReviewSchema } from './reviews.model'
import { IRoom, RoomSchema } from './room.model'
type TCheapestRoom = {
roomType: string
bedType: string
lastPrice: number
actualPrice: number
}
export interface IProperty {
propertyType: string
name: string
description: string
city: string
photos: [string]
cheapestRoom: TCheapestRoom
adress: string
distance: number
cancellationPolicy: string
meals: string
funThingsToDo: [string]
accessibility: [string]
rooms: IRoom[]
reviews: IReview[]
}
interface IPropertyDocument extends IProperty, Document {
createdAt: Date
updatedAt: Date
// rooms: Types.Array<IRoom>
}
const PropertySchema = new Schema<IPropertyDocument>(
{
propertyType: { type: String, required: true },
name: { type: String, required: true },
description: { type: String, required: true },
city: { type: String, required: true },
photos: { type: [String] },
cheapestRoom: {
roomType: { type: String },
bedType: { type: String },
lastPrice: { type: Number },
actualPrice: { type: Number },
},
adress: { type: String, required: true },
distance: { type: Number, required: true },
cancellationPolicy: { type: String, required: true },
meals: { type: String, required: true },
funThingsToDo: { type: [String] },
accessibility: { type: [String] },
rooms: [RoomSchema],
reviews: [ReviewSchema],
},
{
timestamps: true,
}
)
const PropertyModel = model<IPropertyDocument>('Property', PropertySchema)
export default PropertyModel
Subdocument room model:
export interface IRoom {
roomType: string
bedTypes: [string]
roomFacilities: [string]
sleeps: number
lastPrice: number
actualPrice: number
cancellation: string
payment: string
breakfast: string
unavailableDates: [Date]
}
export interface IRoomDocument extends IRoom, Document {
createdAt: Date
updatedAt: Date
}
export const RoomSchema = new Schema<IRoomDocument>(
{
roomType: { type: String, required: true },
bedTypes: { type: [String], required: true },
roomFacilities: { type: [String], required: true },
sleeps: { type: Number, required: true, default: 2 },
lastPrice: { type: Number, required: true },
actualPrice: { type: Number, required: true },
cancellation: { type: String, required: true },
payment: { type: String, required: true },
breakfast: { type: String, required: true },
unavailableDates: { type: [Date] },
},
{
timestamps: true,
}
)
const RoomModel = model<IRoomDocument>('Room', RoomSchema)
export default RoomModel
room controller:
import PropertyModel from '../models/property.model'
import RoomModel from '../models/room.model'
const updateRoom = async (req: Request, res: Response) => {
try {
const updatedProperty = await PropertyModel.findOneAndUpdate(
{ _id: req.params.propertyId, 'rooms._id': req.params.roomId },
{
$set: { 'rooms.$': req.body },
},
{
new: true,
}
)
res.status(201).json(updatedProperty)
} catch (error) {
console.log(error)
res.status(400).json(error)
}
}
export { addNewRoom, deleteRoom, updateRoom }
I want to be able updating my subdocuments, in this case rooms using property id and room id.
How can i update this subdocument ?

model in mongodb user and product ref not working

my code does not working model of mongodb user and product ref does not work for me
and showing
error
Order validation failed: user: Path user is required., orderItems.0.product: Path product is required.
how can i solve it please help me
import mongoose from "mongoose";
const orderSchema = mongoose.Schema(
{
user: {
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: "User",
},
orderItems: [
{
name: { type: String, required: true },
qty: { type: Number, required: true },
image: { type: String, required: true },
price: { type: Number, required: true },
product: {
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: "Product",
},
},
],
shippingAddress: {
address: { type: String, required: true },
city: { type: String, required: true },
postalCode: { type: String, required: true },
country: { type: String, required: true },
},
paymentMethod: {
type: String,
required: true,
},
paymentResult: {
id: { type: String },
status: { type: String },
update_time: { type: String },
email_address: { type: String },
},
taxPrice: {
type: Number,
required: true,
default: 0.0,
},
shippingPrice: {
type: Number,
required: true,
default: 0,
},
itemsPrice: {
type: Number,
required: true,
default: 0,
},
totalPrice: {
type: Number,
required: true,
default: 0,
},
isPaid: {
type: Boolean,
required: true,
default: false,
},
paidAt: {
type: Date,
},
isDelivered: {
type: Boolean,
required: true,
default: false,
},
deliveredAt: {
type: Date,
},
},
{
timestamps: true,
}
);
export const Order= mongoose.model("Order", orderSchema);
enter image description here

Advanced search with mongoose

I have an query object
const query = {
brand : BMW,
yearFrom : 2000,
yearTo : 2003,
price : 7000,
};
I am trying to find every BMW which is made between 2000 and 2003 included.
I am trying in this way but it doesn't work
if (query.yearFrom) {
return offerModel.find({query,year : {$gte : query.yearFrom }}, function(err,arr) {console.log(err,arr)}).skip(offset).limit(12);
}
Here's the mongoose schema
const mongoose = require('mongoose');
const offerSchema = new mongoose.Schema({
brand: {
type: String,
required: true,
},
model: {
type: String,
required: true,
},
year: {
type: Number,
required: true,
},
color: {
type: String,
required: true,
},
power: {
type: Number,
required: true,
},
mileage: {
type: Number,
required: true,
},
populatedState: {
type: String,
required: true,
},
price: {
type: Number,
required: true,
},
condition : {
type: String,
required: true,
},
doors: {
type: Number,
required: true,
},
description: {
type: String,
required: true,
},
transmission: {
type: String,
required: true,
},
engineType: {
type: String,
required: true,
},
category: {
type: String,
required: true,
},
imageURLs : [],
imageIds : [],
creator: {
type: mongoose.Types.ObjectId,
ref: 'user'
},
})
module.exports = mongoose.model('offers', offerSchema);
Sample data from database
_id:60fe98301b76642e04a31c45,
imageURLs:[],
imageIds : [],
brand:BMW,
model:335,
year:2000,
color:White,
doors:4,
power:130
mileage:30000,
populatedState:Sofia,
price:7000,
condition:Used,
description:qweqweqweqe,
transmission:Automatic gearbox,
engineType:Petrol,
category:Sedan,
creator:60fe97d11b76642e04a31c44,
__v:0,
If i put only query it find brand,model and etc.But it doesn't get year search correctly.
I will be glad if you guys have some ideas how can i fix that
Thanks !
Try this
offerModel.find({
$and: [
{ brand :query.brand },
year : {
$gte: query.yearTo,
$lt: query.yearFrom
}
]
}, function (err, results) {
...
}

MongoDB - How to Update or Insert object in array

I have the following collection
{
"likes": [],
"_id": "6086f47a3e8c0411f0a66d22",
"creator": "dimer",
"picture": "",
"title": "",
"body": "hello world",
"comments": [
{
"isReady": true,
"likes": [],
"_id": "6086fcf33e8c0411f0a66d25",
"creatorId": "607e50a16e852544d41a1d9d",
"creator": "dimer",
"body": "hello world",
"replies": [],
"timestamp": 1619459315854
},
],
"createdAt": "2021-04-26T17:12:26.632Z",
"updatedAt": "2021-04-27T04:22:28.159Z",
"__v": 0
},
I want to push into comment.replies a new reply if the comment and the post exists.
How to Update or Insert object into a nested array with conditions?
I tried this:
module.exports.createReply = async (req, res) => {
const user_ID = req.body.creatorId;
const post_ID = req.params.id;
const comment_ID = req.body.commentId;
if (!ID.isValid(user_ID) && !ID.isValid(post_ID) && !ID.isValid(comment_ID)) {
return res.status(400).send("ID unknown");
}
try {
console.log("hello woorld");
const reply = {
creatorId: user_ID,
creator: req.body.creator,
body: req.body.body,
timestamp: new Date().getTime(),
};
console.log("reply", reply);
await PostModel.findById(post_ID, (err, docs) => {
console.log(comment_ID);
const comment = docs.comments.find((comment) =>
comment._id.equals(comment_ID)
);
console.log("comment", comment);
if (!comment) return res.status(404).send("comment not found" + err);
comment.replies = [...comment.replies, reply];
return docs.save((err, docs) => {
if (!err) return res.status(200).send(docs);
return res.status(400).send(err);
});
});
} catch (error) {
return res.status(400).send(err);
}
};
I think I'm not reaching the replies because I'm getting this error:
{
"errors": {
"comments.4.creator": {
"name": "ValidatorError",
"message": "Path `creator` is required.",
"properties": {
"message": "Path `creator` is required.",
"type": "required",
"path": "creator"
},
"kind": "required",
"path": "creator"
}
},
"_message": "post validation failed",
"name": "ValidationError",
"message": "post validation failed: comments.4.creator: Path `creator` is required."
}
This is my model:
const nongoose = require("mongoose");
const PostSchema = nongoose.Schema(
{
creatorId: {
type: String,
// trim: true,
// required: true,
},
creator: {
type: String,
trim: true,
required: true,
},
title: {
type: String,
maxlength: 80,
},
body: {
type: String,
trim: true,
maxlength: 250,
required: true,
},
picture: {
type: String,
},
video: {
type: String,
},
likes: {
type: [String],
require: true,
},
comments: {
required: true,
type: [
{
isReady: {
type: Boolean,
default: true,
},
creatorId: {
type: String,
required: true,
},
creator: {
type: String,
required: true,
},
timestamp: Number,
body: {
type: String,
required: true,
trim: true,
},
likes: {
type: [String],
required: true,
},
replies: {
require: true,
type: [
{
isReady: {
type: Boolean,
default: true,
},
creatorId: {
type: String,
required: true,
},
creator: {
type: String,
required: true,
},
body: {
type: String,
required: true,
trim: true,
},
timestamp: Number,
},
],
},
},
],
},
},
{
timestamps: true,
}
);
module.exports = nongoose.model("post", PostSchema);
Like the error says, Path creator is required.
Make sure the reply has the 'creator' field.
To get the updated document in the update’s return value, you need to use findOneAndUpdate 1 or findAndModify methods. Both the methods have a parameter where you can specify to return the updated document. Note that the Mongoose ODM has corresponding methods, but may have slightly different syntax.
My solution:
module.exports.createReply = async (req, res) => {
const user_ID = req.body.creatorId;
const post_ID = req.params.id;
const comment_ID = req.body.commentId;
if (!ID.isValid(user_ID) && !ID.isValid(post_ID) && !ID.isValid(comment_ID)) {
return res.status(400).send("ID unknown");
}
try {
const reply = {
creatorId: user_ID,
creator: req.body.creator,
body: req.body.body,
timestamp: new Date().getTime(),
};
const query = { _id: post_ID };
const update = { $push: { "comments.$[elem].replies": reply } };
const options = { new: true, arrayFilters: [{ "elem._id": comment_ID }] };
await PostModel.findOneAndUpdate(query, update, options);
let updated = await PostModel.findOne({ _id: post_ID });
return res.status(200).send({
data: updated.comments.find((comment) => comment._id.equals(comment_ID)),
});
} catch (err) {
return res.status(400).send({ err: err });
}
};

Mongoose findByIdAndUpdate : can't update an array field

I'm new to mongoose and i have a problem.
In my app, i have a Travel model like this:
const travelSchema = new mongoose.Schema({
title: {
type: String,
required: [true, 'Please add a title'],
trim: true,
maxlength: [50, 'Title can not be more than 50 characters'],
},
cities: [
{
type: mongoose.Schema.Types.ObjectId,
ref: 'City',
},
],
});
and a City model like this :
const citySchema = new mongoose.Schema({
name: {
type: String,
required: true,
trim: true,
},
location: {
type: {
type: String,
enum: ['Point'],
required: true,
},
coordinates: {
type: [Number],
required: true,
},
},
travels: [
{
type: mongoose.Schema.Types.ObjectId,
ref: 'Travel',
},
],
});
So when i delete a travel, i want to remove the travel_id from the 'travels' field of the cities which are concerned by the travel.
Here i am:
exports.deleteTravel = asyncHandler(async (req, res, next) => {
const travel = await Travel.findByIdAndDelete(req.params.id);
travel.cities.map(cityId => {
City.findByIdAndUpdate(
cityId,
{ travels: travels.filter(id => id !== travel._id) },
{
new: true,
runValidators: true,
}
);
});
res.status(200).json({ success: true, data: {} });
});
I got this error message: Error: travels is not defined
Do you have any idea why?
Many thanks !
It's working like this :)
exports.deleteTravel = asyncHandler(async (req, res, next) => {
const travel = await Travel.findByIdAndDelete(req.params.id);
travel.cities.map(async cityId => {
await City.findByIdAndUpdate(
cityId,
{ $pull: { travels: travel._id } },
{
new: true,
runValidators: true,
}
);
});

Resources