Mongoose findByIdAndUpdate : can't update an array field - arrays

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,
}
);
});

Related

Failed to save data into postgres database using sequelize.js, but system return column multiple times

While trying to save data into postgres database using sequelize BlogModel.create() system failed to save the data into table and server is returning columns createdat, updatedat, multiple times in console. ( please see below ). In the scheme I have added the column only once, can someone advise on this issue here ?
Executing (default): INSERT INTO "userBlogs" ("id","email","blogdetails","tags","createdat","updatedat","createdAt","updatedAt") VALUES (DEFAULT,$1,$2,$3,$4,$5,$6,$7) RETURNING "id","email","blogdetails","tags","createdat","updatedat","createdAt","updatedAt";
//userBlogs.js
'use strict';
module.exports = (sequelize, DataTypes) => {
const userBlogs = sequelize.define('userBlogs', {
id: {
type: DataTypes.INTEGER(10),
allowNull: false,
primaryKey: true,
autoIncrement: true
},
email: {
type: DataTypes.STRING(255),
allowNull: false
},
blogdetails: {
type: DataTypes.TEXT,
allowNull: false
},
tags: {
type: DataTypes.STRING(255),
allowNull: false
},
createdat: {
type: DataTypes.DATE,
allowNull: false,
defaultValue: DataTypes.NOW
},
updatedat: {
type: DataTypes.DATE,
allowNull: false,
defaultValue: DataTypes.NOW
}
}, {
timestamps: true,
tableName: 'userBlogs'
});
return userBlogs;
};
//server.js
const usersBlogSchema = require('./modals/userBlogs');
const BlogModel = usersBlogSchema(sequelize, DataTypes);
app.post('/service/createblogs', async (req, res, next)=> {
try {
const userEmail = req.body.email;
const blogDetails = req.body.blogValue;
const tags = req.body.tagValue;
if (Object.keys(req.body).length === 0) {
res.status(403).json({ fail: "Invalid blog request or blog request is blank !" });
} else {
var requestData = {email:userEmail, blogdetails:blogDetails, tags:tags };
const createBlogRequest = await BlogModel.create(requestData);
res.status(200).json({ success: true });
}
} catch (e) {
console.log(e)
return next(e);
}
});
Returning createdAt and updatedAt multiple times because you have added columns (createdAt and updatedAt )and also timestamps:true ,
timestamps also adds these both columns
use either columns or timestamps
'use strict';
module.exports = (sequelize, DataTypes) => {
const userBlogs = sequelize.define('userBlogs', {
id: {
type: DataTypes.INTEGER(10),
allowNull: false,
primaryKey: true,
autoIncrement: true
},
email: {
type: DataTypes.STRING(255),
allowNull: false
},
blogdetails: {
type: DataTypes.TEXT,
allowNull: false
},
tags: {
type: DataTypes.STRING(255),
allowNull: false
},
}, {
timestamps: true,
tableName: 'userBlogs'
});
return userBlogs;
};

Sequelize hasOne and belongsTo relationship problem

i am using PostgreSQL with Sequelize ORM to create my db.
I have this models:
models.js
const Users = db.define("users", {
name: {
type: DataTypes.STRING,
},
lastname: {
type: DataTypes.STRING,
},
sector: {
type: DataTypes.STRING,
},
email: { type: DataTypes.STRING, unique: true, allowNull: false },
password: { type: DataTypes.STRING, allowNull: false },
points: { type: DataTypes.INTEGER, defaultValue: 0 },
suscripcion: { type: DataTypes.BOOLEAN, defaultValue: false },
preference_id: { type: DataTypes.STRING },
});
const Pronostico = db.define("pronosticos", {
matchId: {
type: DataTypes.STRING,
unique: true,
},
winner: {
type: DataTypes.STRING,
},
goalHome: {
type: DataTypes.INTEGER,
},
goalAway: {
type: DataTypes.INTEGER,
},
});
//REFRESH TOKEN
const RefreshToken = db.define("refreshTokens", {
token: {
type: DataTypes.STRING,
},
expiryDate: {
type: DataTypes.DATE,
},
userId: {
type: DataTypes.STRING,
},
});
RefreshToken.createToken = async function (user) {
let expiredAt = new Date();
expiredAt.setSeconds(expiredAt.getSeconds() + config.jwtRefreshExpiration);
let _token = uuidv4();
let refreshToken = await this.create({
token: _token,
userId: user.id,
expiryDate: expiredAt.getTime(),
});
return refreshToken.token;
};
RefreshToken.verifyExpiration = (token) => {
return token.expiryDate.getTime() < new Date().getTime();
};
This are the Relationships:
Users.hasMany(Pronostico, { as: "pronosticos" });
Pronostico.belongsTo(Users, { foreignKey: "userId", as: "user" });
RefreshToken.belongsTo(User, {
foreignKey: 'userId', targetKey: 'id'
});
User.hasOne(RefreshToken, {
foreignKey: 'userId', targetKey: 'id'
});
Somewhere on my server, I have this controller which creates a refreshToken:
let refreshToken = await RefreshToken.createToken(user);
The problem is that I get an error that says "column userId doesnt exist in refreshTokens relationship.
Maybe I have some issues with the relationships but I think they are OK.
Any suggestion?

user_team is not associated to team

I'm new to sequelize as a user and I use the 'many to many' option in the team situation. I created my code but : user_team is not associated to team! i am getting error how can i fix it. I'm doing it for a task, I would be very happy if you help me.tanks
If the structure is also wrong, can you tell me what my mistakes are?
userteam.js
module.exports = (sequelize, DataTypes) => {
const UserTeam = sequelize.define(
"user_team",
{
user_team_id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
user_id: {
type: DataTypes.INTEGER,
primaryKey: false,
references: {
model: "user",
key: "user_id",
},
onDelete: "cascade",
onUpdate: "cascade",
unique: "unique-team-per-user",
},
team_id: {
type: DataTypes.INTEGER,
primaryKey: false,
references: {
model: "team",
key: "team_id",
},
onDelete: "cascade",
onUpdate: "cascade",
unique: "unique-team-per-user",
},
},
{ timestamps: false, tableName: "user_team", underscored: true }
);
UserTeam.associate = (models) => {
UserTeam.belongsTo(models.User, {
foreignKey: "user_id",
targetKey: "user_id",
as: "User",
});
UserTeam.belongsTo(models.Team, {
foreignKey: "team_id",
targetKey: "team_id",
as: "Team",
});
};
return UserTeam;
};
user.js
module.exports = (sequelize, DataTypes) => {
const User = sequelize.define(
"user",
{
user_id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
firstName: {
type: DataTypes.STRING,
allowNull: false,
},
lastName: {
type: DataTypes.STRING,
allowNull: false,
},
password: {
type: DataTypes.STRING,
allowNull: false,
},
email: {
type: DataTypes.STRING,
allowNull: false,
},
},
{ timestamps: true, tableName: "user", underscored: true }
);
User.associate = (models) => {
User.hasMany(models.Todo, {
as: "todos",
foreignKey: "userId",
});
User.hasMany(models.Team, {
as: "teams",
foreignKey: "admin",
});
User.belongsToMany(models.Team, {
as: "TeamsForUser",
through: models.UserTeam,
foreignKey: "user_id",
});
};
return User;
};
team.js
module.exports = (sequelize, DataTypes) => {
const Team = sequelize.define(
"team",
{
team_id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
teamName: {
type: DataTypes.STRING,
allowNull: false,
},
admin: {
type: DataTypes.INTEGER,
allowNull: false,
},
},
{ tableName: "team", underscored: true }
);
Team.associate = (models) => {
Team.belongsTo(models.User, {
as: "user",
foreignKey: "admin",
});
Team.belongsToMany(models.User, {
as: "UserInTeam",
through: models.UserTeam,
foreignKey: "team_id",
});
};
return Team;
};
controller.js
const getAll = async (req, res, next) => {
try {
const myTeams = await Team.findAll({
include: [{ model: UserTeam }],
});
myTeams.forEach((element) => {
console.log(element.get());
});
return res.status(200).json(myTeams);
} catch (err) {
console.log(err.message);
res.status(500).json({ message: err });
}
};
i solved this problem
just add to index database config js
db.users.belongsToMany(db.team, {
as: "teams",
through: "user_team",
foreignKey: "user_id",
});
db.team.belongsToMany(db.users, {
as: "users",
through: "user_team",
foreignKey: "team_id",
});
enter code here

Submitting two forms in React. One returns string while other returns json

I'm building one of my first admin areas for a site in React. I'm using mongoose and MongoDB. When I submit the form to add an artist to the db it does everything correctly and I can see it return the data as a JSON Object. When I submit a form that adds a piece of artwork to an artist it looks like it works but it actually does not add anything to the database as the data is sent as a string. I believe the only difference is one route is a POST and one is a Patch. I can't find any other difference. How can I make my form send data as a JSON instead of a string.
My Model
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const artistSchema = new Schema({
first_name: { type: String, required: true },
last_name: { type: String, required: true },
artist_painter: { type: Boolean, required: false},
artist_sculptor: { type: Boolean, required: false},
artist_other: { type: Boolean, required: false},
featured_image: { type: String, required: false},
artwork:[
{
type: { type: String, required: false},
title: { type: String, required: false},
width: { type: Number, required: false},
length: { type: Number, required: false},
depth: { type: Number, required: false},
image: { type: String, required: false},
media: { type: String, required: false},
price: { type: Number, required: false},
newRelease: { type: Boolean, required: false}
}
]
});
const Artist = mongoose.model("Artist", artistSchema);
module.exports = Artist
API Routes
// Matches with "/api/artists"
router.route("/")
.get(artistsController.findAll)
.post(artistsController.create);
// Matches with "/api/artists/:id"
router
.route("/:id")
.get(artistsController.findById)
.put(artistsController.update)
.delete(artistsController.remove);
// Matches with "/api/artists/art/:id"
router
.route("/art/:id")
.patch(artistsController.addArtById)
module.exports = router;
Artist Controller
const db = require("../models");
// Defining methods for the ArtistsController
module.exports = {
findAll: function(req, res) {
db.Artist
.find(req.query)
.then(dbModel => res.json(dbModel))
.catch(err => res.status(422).json(err));
},
findById: function(req, res) {
db.Artist
.findById(req.params.id)
.then(dbModel => res.json(dbModel))
.catch(err => res.status(422).json(err));
},
create: function(req, res) {
db.Artist
.create(req.body)
.then(dbModel => res.json(dbModel))
.catch(err => res.status(422).json(err));
},
update: function(req, res) {
db.Artist
.findOneAndUpdate({ _id: req.params.id }, req.body)
.then(dbModel => res.json(dbModel))
.catch(err => res.status(422).json(err));
},
remove: function(req, res) {
db.Artist
.findById({ _id: req.params.id })
.then(dbModel => dbModel.remove())
.then(dbModel => res.json(dbModel))
.catch(err => res.status(422).json(err));
},
addArtById: function(req, res) {
db.Artist
.findOneAndUpdate({ _id: req.params.id }, {$push: { artwork: req.body } } )
.then(dbModel => res.json(dbModel))
.catch(err => res.status(422).json(err));
},
};

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

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
}
);

Resources