sequelize users.findOne using two parameters - javascript

I would like to use users.findOne method using two params like in the example below, not just with the id or name but with both
const user = await Tags.findOne({
where: { id: ID, name: NAME },
});

As far as I know you code should work, but you can try the following approach:
const user = await Tags.findAll({
where: {
[Op.and]: [
{ id: ID },
{ name: NAME }
]
}
});
You can define operators for the where clause manually. For reference see https://sequelize.org/master/manual/model-querying-basics.html#applying-where-clauses

here is an example . you have to user the Op from sequelize.
const { Op } = require("sequelize");
const isFoundNumber = await db.users.findOne({
where: {
[Op.or]: [
{
mobile_number: params.mobile_number,
},
{ email: params.email },
],
},
});
if (isFoundNumber != null) {
let user = basicDetails(isFoundNumber);
if (params.mobile_number == user.mobile_number) {
reject({
status: false,
errorMessage: `Mobile Number ${params.mobile_number} already regstered`,
data: basicDetails(isFoundNumber),
});
}
if (params.email === user.email) {
reject({
status: false,
errorMessage: `Email Account ${params.email} already regstered`,
data: user,
});
}
}

Related

variable value is not changing in a map function paired with mongoose querys

i am working on a mern project where i need to create an agenda that contains an attribute as array of appointments types.
in the nodejs api i am declaring a var typeRefs = [];
if a type is present in the types model i insert its ref in the previous array else i create the type and insert the new type ref in the previous array, finally i create the agenda doc based on the typeRefs array, but the array is empty outside the map function scope , inside the map function scope i can see the array values changing.
//agenda model
const agendaSchema = mongoose.Schema(
{
name: String,
types: [{ type: mongoose.Schema.Types.ObjectId, ref: "Type" }],
establishment: {
type: mongoose.Schema.Types.ObjectId,
ref: "Establishment",
},
template: { type: mongoose.Schema.Types.ObjectId, ref: "Template" },
isActive: { type: Boolean, default: true },
},
{ timestamps: true }
);
var Agenda = mongoose.model("Agenda", agendaSchema);
export default Agenda;
// types model
import mongoose from "mongoose";
const typeSchema = mongoose.Schema(
{
name: String,
duration: Number,
color: String,
online: { type: Boolean, default: true },
establishment: {
type: mongoose.Schema.Types.ObjectId,
ref: "Establishment",
},
},
{ timestamps: true }
);
var Type = mongoose.model("Type", typeSchema);
export default Type;
// api function for agenda creation
export const add = async (req, res) => {
var data = req.body;
try {
var typesRefs = [];
data.types.map((type) => {
Type.find({ name: type.text.toUpperCase() }, (err, res) => {
if (res.length === 0) {
const newType = new Type({
name: type.text.toUpperCase(),
establishment: data.establishment,
});
newType.save();
typesRefs = [...typesRefs, newType._id];
} else {
typesRefs = [...typesRefs, type._id];
}
});
});
console.log(typesRefs);
await Agenda.create({ ...data, types: typesRefs });
res.status(200).json({ message: "Agenda created successfully" });
} catch (error) {
console.log(error);
res.status(401).json({ message: "An error occured !" });
}
};
the trick is to use a for loop instead of map function.
export const add = async (req, res) => {
var data = req.body;
var typeRefs = [];
try {
for (let i = 0; i < data.types.length; i++) {
const typeExist = await Type.find({
name: data.types[i].text.toUpperCase(),
});
if (typeExist.length === 0) {
const newType = await Type.create({
name: data.types[i].text.toUpperCase(),
establishment: data.establishment,
});
typeRefs = [...typeRefs, newType._id];
} else {
typeRefs = [...typeRefs, data.types[i]._id];
}
}
console.log(typeRefs);
await Agenda.create({ ...data, types: typeRefs });
res.status(200).json({ message: "Agenda created successfully" });
} catch (error) {
console.log(error);
res.status(401).json({ message: "An error occured !" });
}
};

mongodb having multiple conditions for $nin and data coming from the client

I'm trying to do a query based on some data but apparently, $nin is not reading the returned values from the function.
My goal is to not show all the users I've followed on the recommended section where there is a get request to receive all the users registered on the db.
I do have the following users on the function, however when I try to do the query, its not working and I've tried for hours fixing that problem.
At username: { $nin: [allFollowers.forEach((following) => following.username)] => Doing this, doesnt work, however when I put strings from the list of following users such as 'user1', 'user2', it works. My api updates on the client and I dont see those two users I follow on the recommended section.
I'd appreciate if you could help me.
exports.recommendedUsers = async function (req, res) {
// all following users in an array
const { followingUsers } = req.body;
/* console.log(followingUsers) =>
[
{
username: 'user1',
avatar: '//www.gravatar.com/avatar/c76fa83b3saddasdas2c04a59d6e063918badbf53?s=200&r=pg&d=mm'
},
{
username: 'user2',
avatar: '//www.gravatar.com/avatar/3758e369b058b393541asdasda4d0e8a1d57402?s=200&r=pg&d=mm'
},
{
username: 'uiser3',
avatar: 'https://static-cdn.jtvnw.net/jtv_user_pictures/bobross-profile_image-0b9dd16cascad7a9bb16b5-70x70.jpeg'
},
{
username: 'user4',
avatar: 'https://static-cdn.jtvnw.net/jtv_user_pictures/82b63a01-628f-4c81-9b05-dd3a501asdasd1fdda-profile_image-70x70.png'
},
{
username: 'user5',
avatar: '//www.gravatar.com/avatar/93cd495a412a1b2asdadabe9b9c72bc246e271?s=200&r=pg&d=mm'
}
] */
let allFollowers = [];
let following = req.body.followingUsers.forEach((follow) =>
allFollowers.push(JSON.stringify(follow.username))
);
console.log(`this is all followers: ${allFollowers}`);
try {
const user = User.find(
{
_id: { $ne: req.user.id },
username: {
$nin: [allFollowers.forEach((following) => following.username)], // not working
},
},
function (err, users) {
let userMap = {};
users.forEach(function (user) {
userMap[user._id] = user;
});
const arrayData = Object.values(userMap);
return res.json(arrayData);
}
).select('-password');
} catch (e) {
console.log(e.message);
}
};
You are using foreach function, that is wrong:
username: {
$nin: [allFollowers.forEach((following) => following.username)],
}
The return value of foreach is undefined, use map function.
try {
const user = User.find(
{
_id: { $ne: req.user.id },
username: {
$nin: allFollowers.map((following) => following.username),
},
},
function (err, users) {
let userMap = {};
users.forEach(function (user) {
userMap[user._id] = user;
});
const arrayData = Object.values(userMap);
return res.json(arrayData);
}
).select('-password');
} catch (e) {
console.log(e.message);
}

How to retreive an object from an array of Objects in mongodb given a objectid

I have an array of reviews, I want to retrieve only a review from an array of objects inside a schema.
Here is my schema:
const sellerSchema = new mongoose.Schema({
user: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
unique: true,
},
reviews: [
{
by: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
unique: true,
},
title: {
type: String,
},
message: {
type: String,
},
rating: Number,
imagesUri: [{ String }],
timestamp: {
type: Date,
default: Date.now,
},
},
],
});
How can I get a single review from the array if 'by' will be req.user._id. I have the previous code, but it is not working to retrieve the review only that satisfies the query.
try {
const seller_id = mongoose.Types.ObjectId(req.params._id);
const review = await Seller.findOne(
{ _id: seller_id },
{ reviews: { $elemMatch: { by: req.user._id } } } //get the review that matches to the user_id
);
res.status(200).send(review);
} catch (err) {
//sends the status code with error code message to the user
res.status(502).send({
error: "Error retreiving review.",
});
}
This retrieves the whole seller document, but I just want to retrieve the object review with the given a user_id === by: ObjectID
give it a try
try {
const seller_id = mongoose.Types.ObjectId(req.params._id);
const review = await Seller.findOne(
{ _id: seller_id , "reviews.by": req.user._id}, { "reviews.$": 1 }
);
res.status(200).send(review);
}
Try to cast also the user _id as ObjectId and unify your conditions into a single object:
try {
const seller_id = mongoose.Types.ObjectId(req.params._id);
const user_id = mongoose.Types.ObjectId(req.user._id);
const review = await Seller.findOne({
_id: seller_id,
reviews: { $elemMatch: { by: user_id } },
});
res.status(200).send(review);
} catch (err) {
//sends the status code with error code message to the user
res.status(502).send({
error: 'Error retreiving review.',
});
}

MongoDB only updates partially

My model has "id", "liked", "likedBy" and "matched" fields.
I can update my database and add id according to my hypotethical likes; it stores target's id to my current user's liked field, current user's id to target's likedBy field.
I'm trying to achieve, if a user has both liked and likedBy id matching then put liked id to my matched field on both users, but I can't for some reason. It just doesn't care if statement there.
Any ideas why?
//like user by using it's id. update it to liked
app.put("/like/:id", auth, async (req, res) => {
try {
const user = await User.findById(req.params.id);
const loggedUser = await User.findById(req.user.id).select("-password");
//check if it is already liked
if (
user.likedBy.filter((like) => like.user.toString() === req.user.id)
.length > 0
) {
return res.status(400).json({ msg: "Already Liked" });
}
user.likedBy.unshift({ user: req.user.id });
loggedUser.liked.unshift({ user: req.params.id });
await user.save();
await loggedUser.save();
//check matching
if (user.likedBy === user.liked) {
user.matched.unshift({ user: req.user.id });
}
await user.save();
await loggedUser.save();
res.status(200).send("Liked!");
} catch (err) {
console.error(err.message);
res.status(500).send("Server Error");
}
});
My Schema:
const mongoose = require("mongoose");
const UserSchema = new mongoose.Schema({
email: {
type: String,
required: true,
unique: true,
},
password: {
type: String,
required: true,
},
firstname: {
type: String,
required: true,
},
lastname: {
type: String,
required: true,
},
picture: {
data: Buffer,
contentType: String,
},
age: {
type: Number,
required: true,
},
gender: {
type: String,
required: true,
},
job: {
type: String,
required: true,
},
desc: {
type: String,
default: "Hasn't written anything yet.",
},
liked: [{}],
likedBy: [{}],
matched: [{}],
});
module.exports = User = mongoose.model("user", UserSchema);
I found the mistake I made.
I'm trying to compare objects, which isn't possible really. I got index of my array then extracted the data I need and stored it into value1 & value2.
I found my mistake the moment I console.log'ed my conditions as below:
if(console.log(user.liked) === console.log(user.likedBy)){
...}
Working version:
//like user by using it's id. update it to liked
app.put("/like/:id", auth, async (req, res) => {
try {
const user = await User.findById(req.params.id);
const loggedUser = await User.findById(req.user.id).select("-password");
//check if it is already liked
if (
user.likedBy.filter((like) => like.user.toString() === req.user.id)
.length > 0
) {
return res.status(400).json({ msg: "Already Liked" });
} else {
user.likedBy.unshift({ user: req.user.id });
loggedUser.liked.unshift({ user: req.params.id });
await user.save();
await loggedUser.save();
const value1 = user.likedBy[0].user;
const value2 = user.liked[0].user;
if (value1 === value2) {
user.matched.unshift({ user: req.user.id });
loggedUser.matched.unshift({ user: req.params.id });
await user.save();
await loggedUser.save();
res.status(200).send("Liked & Matched!");
} else {
res.status(200).send("Liked!");
}
}
} catch (err) {
console.error(err.message);
res.status(500).send("Server Error");
}
});

User data not returning anything from query call

I'm not sure which part I might be doing wrong. I was hoping to get some advice.
The query I am using in GraphiQL is:
query getUser($id:Int!) {
user(id:$id) {
id
email
}
}
For the backend I am using NodeJS. I am also declaring the user type as:
const UserType = new GraphQLObjectType({
name: 'User',
fields: () => ({
id: { type: GraphQLID },
email: { type: GraphQLString }
})
});
My root query is:
const RootQuery = new GraphQLObjectType({
name: 'RootQueryType',
fields: {
user: {
type: UserType,
args: { id: { type: GraphQLInt } },
resolve(parentValue, args) {
const query = `SELECT * FROM users WHERE id=$1`;
const values = [ args.id ];
dbQuery.query(query, values).then(({ rows }) => {
console.log(rows[0]);
return rows[0];
});
}
}
}
});
const schema = new GraphQLSchema({ query: RootQuery });
app.use(
'/api/v1/graphql',
graphqlHTTP({
schema: schema,
graphiql: true
})
);
What I get in return is:
{
"data": {
"user": null
}
}
I was hoping to know what I might be doing wrong that is resulting in null being returned instead of the data that I am querying from the database.
Thank you for all the help.
It will be much more clear if you use with await
const RootQuery = new GraphQLObjectType({
name: 'RootQueryType',
fields: {
user: {
type: UserType,
args: { id: { type: GraphQLInt } },
resolve: async(parentValue, args) {
const query = `SELECT * FROM users WHERE id=$1`;
const values = [ args.id ];
const rows = await dbQuery.query(query, values);
return rows[0];
}
}
}
});
When using a promise and returning anything inside the promise will only return the result to the promise that is executed. It will not be returning as a whole to the parent function.
You can also return the whole promise function like below
return dbQuery.query(query, values)

Categories

Resources