Where value is "undefined" when using Sequelize.not - node.js

Using a simple sequelize query I keep getting error message "Invalid value { indefined: 0 }" when using the sequelize.not function as below
let total = await userDB.tblSMSSent.findOne({
attributes: [[sequelize.fn('COUNT', 'id'), 'numMessages']],
where: {
user: userName,
messageID: { [sequelize.not]: '0' }
}, logging: false
})
When I run the query without the 'MessageID: { [sequelize.not]: 0 }' filter it works fine (although with incorrect results). How can I use the sequelize.not function correctly here?
In the database the messageId column is nchar(20)

You need to use sequelize.Op.not:
let total = await userDB.tblSMSSent.findOne({
attributes: [[sequelize.fn('COUNT', 'id'), 'numMessages']],
where: {
user: userName,
messageID: { [sequelize.Op.not]: '0' }
}, logging: false
})

Related

find various entities by ids from multiple tables

I am using nestjs and typeorm for backend, currently have 3 entities in database. On many occasions, I need to find the records in different entites by ids passed from frontend. If any of them is not found, the function will return and stop proceeding.
It may receive 1 to 3 ids from frontend and the outcome should be clearly typed for next step.
I expect to use this function/method as follows:
const {user, organization, invitation}=await this.findEntities({userId, organizationId, invitationId})
// and when I try to do this, it should let me know that property "oganization" does not exist.
const { user, organization } = await this.findEntities({userId: 'abc'})
I stuck at the second use case. Although the return object does not contain any property named organization, it will not give the error prompt.
my code is as follows:
async findEntities(data: Ids) {
const { userId, organizationId, invitationId } = data;
const entities = await Promise.all([
userId ? this.userRepository.findOne({ where: { id: userId } }) : 1,
organizationId
? this.organizationRepository.findOne({
where: { id: organizationId },
})
: 1,
invitationId
? this.invitationRepository.findOne({
where: { id: invitationId },
})
: 1,
]);
if (entities.some((element) => element == null))
throw new NotFoundException();
return {
...(typeof entities[0] === 'number' ? null : { user: entities[0] }),
...(typeof entities[1] === 'number'
? null
: { organization: entities[1] }),
...(typeof entities[2] === 'number'
? null
: { invitation: entities[2] }),
};
}
Can you please help me improve it so that ts could prompt errors when imput and output do not match? Thanks.

How do I check if the objectids are similar?

Below is my function to check if the username in session matches to the person who commented originally:
async sameUser(id,uname){
const blogsCollection = await blogs();
id = ObjectId(id)
let a;
const finder = await blogsCollection.findOne({'comments._id':id});
for(i=0;i<finder.comments.length;i++){
if (finder.comments[i]._id == id) {
a = finder.comments[i].commentuser;
}
}
if (a == uname) return true
else return false
}
This is what the collection looks like in MongoDB:
{
_id: new ObjectId("61f4c62818c9c4633a117beb"),
title: 'my first blog',
body: 'wazzzzzzzzzzzzzzzzzzup',
bloguser: {
_id: new ObjectId("61f22f8bb5c180195ca925df"),
username: 'tom'
},
comments: [{
_id: new ObjectId("61f4ec0a0d4c9731bdbe5f6b"),
comment: 'wow',
commentuser: 'tom'
}
]
}
I am calling the sameUser function this way:
const user = await blogs.sameUser('61f4ec0a0d4c9731bdbe5f6b','tom');
console.log(user);
I don't know why variable "a" always returns undefined, I consoled.log both the ids in the for loop and they display the same thing:
new ObjectId("61f4ec0a0d4c9731bdbe5f6b")
new ObjectId("61f4ec0a0d4c9731bdbe5f6b")
I debugged and checked that it never reaches the statement after the if condition, not sure what's wrong.
Found solution here:
https://whitehorsesblogarchive.wordpress.com/2017/10/15/how-to-compare-mongo-_ids-in-javascript/
Apparently comparing objectIds should be done using equals() instead of "=="

Mongoose - how to fetch specific number and message ID

I'm trying to make the bot basically edit the message of any specific case mentioned for example if i do -case 5 test it will look for case 5 and it's message. So far when i do it, it basically changes the recent case number message, instead of the one i want it to change. like if i do case 5 test and the latest case is #9, it will change 9 instead of 5.
This is how i send the message:
Modlog.findOneAndUpdate({ guildID: msg.channel.guild.id }, { $inc: { 'caseID': 1 } }, { new: true }, async function (err, doc) {
if (err) throw err;
if (!doc) return;
if (doc.modLog.enabled) {
if (msg.channel.guild.channels.get(doc.modLog.channelID)) {
let m = await msg.channel.guild.channels.get(doc.modLog.channelID).createMessage({
embed: {
title: `${action} | Case #${doc.caseID}`,
color: colour,
fields: [
{
name: 'User',
value: user,
inline: true
},
{
name: 'Moderator',
value: moderator ? moderator : 'No issuer.',
inline: true
},
{
name: 'Reason',
value: reason ? reason : 'No reason.'
}
]
}
});
doc.messageID = m.id;
doc.type = action;
doc.caseID = doc.caseID;
//doc.caseID = m.id
doc.moderatorID = moderator,
doc.targetID = user
doc.save();
}
}
})
that is how i send my message. And you can see i'm storing the things so when someone changes a specific case's reason, for example: case 5 spamming, i would want it to look for caseID 5, and then edit the message through it's ID. but i'm not sure how am i doing it wrong. I'm trying to make each case store it's own message ID and i would really appreciate any help. This is what i use to look for the case and edit's reason.
Modlog.findOne({ guildID: msg.guildID }, async (err, doc) => {
if (err) throw err;
if (!doc.modLog.enabled) return msg.channel.createMessage(`Modlog is not enabled in this server! ${this.emoji.cross}`);
if (isNaN(Number(caseID))) return msg.channel.createMessage(`Case \`#${caseID}\` was not a number! ${this.emoji.cross}`);
if (doc.caseID === undefined) return msg.channel.createMessage(`Couldn\'t find case \`#${caseID}\`! ${this.emoji.cross}`);
const moderator = this.bot.users.get(doc.moderatorID) || {
username: 'Unknown User',
discriminator: '0000'
}
const target = this.bot.users.get(doc.targetID) || {
username: 'Unknown User',
discriminator: '0000'
}
let embed = {
title: `${doc.type} | Case #${doc.caseID}`,
fields: [
{
name: 'User',
value: `${target.username}#${target.discriminator} (${target.id})`,
inline: true
},
{
name: 'Moderator',
value: `${moderator.username}#${moderator.discriminator} (${moderator.id})`,
inline: true
},
{
name: 'Reason',
value: reason
}
]
};
try {
await this.bot.editMessage(doc.modLog.channelID, doc.messageID, { embed: embed });
await msg.channel.createMessage(`Case **#${caseID}** has been updated. ${this.emoji.tick}`);
} catch (e) {
await msg.channel.createMessage(`I\'m unable to edit that case or it has been deleted. ${this.emoji.cross}`);
}
});```
Solution: Search for Case ID
It seems you didn't look for the case ID, and only looked for the guild's ID in the filter parameter.
Modlog.findOneAndUpdate({ guildID: msg.channel.guild.id }, { ... }, { ... }, ... {
...
}
In your code, only guildID was passed into the filter parameter. This causes Mongoose to look for the most recently initialized document for the server. For your case, you should also pass caseID into the filter parameter.
Modlog.findOneAndUpdate({ guildID: msg.channel.guild.id, caseID: caseIDArg }, { ... }, { ... }, ... {
...
}
Replace caseIDArg with your supposed caseID argument in the message's content. For example, args[1] or however you programmed your argument handler to work.
Hope this helped to answer your question!

Mongoose: updateMany() is not working as expected

I'm using mongoose to handle my DB queries. I'm trying to update a set of records entirely using this method. Mode code looks like this:
// prepare database query
const filter = { type: 'company' };
const update = req.body.payload; // payload contains the array of objects (i.e. updated records)
const options = { new: true, runValidators: true }
// find and update the taxonomy record
await Taxonomy.updateMany(filter, update, options);
But whenever I run this query I'm getting following error in the console:
Error [MongooseError]: Invalid update pipeline operator: "_id"
I suppose there is something wrong in my update payload. The req.body.payload looks like this:
[
{
_id: '5ef3d08c745428001d92f896',
type: 'company',
name: 'Company Size',
__v: 0
},
{
_id: '5ef3cdc5745428001d92f893',
type: 'company',
name: 'Company Industry',
__v: 0
}
]
Can you please tell me what actually is wrong here?
This is not the right usage of updateMany() - it is aimed to update many documents with a single change.
To update many documents use bulkwrite() (docs) :
async function myUpdateMany(Model, objectsArray) {
try {
let ops = []
for (let obj of (objectsArray || [])) {
ops.push({
updateOne: {
filter: { platformId: obj.platformId },
update: obj,
upsert: false, // set "true" if you want to add a new document if it doesn't exist
}
})
}
Model.bulkWrite(ops, { ordered: false });
} catch (err) {
throw Error("myUpdateMany error: " + err)
}
}
Regarding runValidators, according to this, it seems to work by default.

Formik, jest, yup : how to test validation?

i can't find a way to test form yup validation:
it('displays error on submit if name is empty', async () => {
const wrapper = mount(<MyFormik/>)
const getForm = () => wrapper.find('form')
wrapper.find('input[name="name"]').simulate('change', {
persist: () => {},
target: {
name: 'name',
value: ''
}
})
wrapper
.find('MyInnerForm')
.props()
.submitForm()
await wait(0) // await next tick or even 1s...
wrapper.update()
expect(
wrapper
.update()
.find('.error')
.exists()
)
.toBeTruthy() // FALSE!
})
No matter if i wait after submit, update wrapper errors prop is always empty.
And the solution here are not working for me:
https://github.com/jaredpalmer/formik/issues/1146
https://github.com/jaredpalmer/formik/issues/110
Looks like wrapper won't update
Here's the log of formik props after submit:
{ errors: {},
label: '',
name: 'name',
type: 'text',
values: { name: '' },
touched: { name: true },
isValidating: false,
status: undefined,
initialValues: { name: '' },
validateOnChange: true,
validateOnBlur: true } }
...
submitCount: 1,
isValid: false,
You can validate the form values directly on your validation schema.
const yup = require('yup')
const contactSchema = yup.object({
name: yup.string()
.required(),
age: yup.number()
.required()
.positive()
.integer()
})
const errors = await contactSchema.validate({
name: 'Kenneth',
age: -35.5
}).catch(function(err) {
return err
});
console.log("errors", errors);
https://runkit.com/kluplau/5defa8cd122cf6001a3034c7
Without seeing your component I'm not entirely sure what's going wrong. This is likely not to be working:
wrapper
.find('MyInnerForm')
.props()
.submitForm()
If your component MyInnerForm contains a Formik form calling submitForm() there will not cause Formik's validation to run. I would instead do something like this:
wrapper.find("form").simulate("submit");
However if that isn't solving your issue I made a full example that you can have a look at here.

Resources