I have data that already saved at mongoodb atlas, but i dont know how to get and display that data to my bot discord reply.
This is how i submit the data
const subregis = "!reg ign:";
client.on("message", msg => {
if (msg.content.includes(subregis)){
const user = new User({
_id: mongoose.Types.ObjectId(),
userID: msg.author.id,
nickname: msg.content.substring(msg.content.indexOf(":") + 1)
});
user.save().then(result => console.log(result)).catch(err => console.log(err));
msg.reply("Data has been submitted successfully")
}
});
This is my schema
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const profileSchema = new Schema({
_id: mongoose.Schema.Types.ObjectId,
userID: String,
nickname: String,
});
module.exports = mongoose.model("User", profileSchema);
And i want to show the data like this, i try this code but didnt work.
client.on("message", msg => {
if (msg.content === "!nickname"){
msg.reply("Your Nickname:", User.findById(nickname))
}
});
In MongoDB, you have a few ways to query data from the database. Some of them are: User.find() (to find multiple documents), User.findById() (to get a document by its id), and User.findOne (to find only the first document which matches the parameters). An example of each of them would be:
User.find({ query }, function (err, data) {
if (err) throw err
console.log(data) // This will return all of the documents which match the query
})
User.findById({ id }, function (err, data) {
if (err) throw err
console.log(data) // This will return the document with the matching id given
})
User.findOne({ query }, function (err, data) {
if (err) throw err
console.log(data) // This will return the first document which matches the query
})
To find the data by the nickname, you would first have to get it by splitting the message content. Then you would have to query the data by using one of the methods mentioned above and then you can respond back. You can do something like this:
client.on('message', async (message) => {
const args = message.slice(1).split(' ')
const command = args.shift().toLowerCase()
const nickname = args.join(' ')
const data = await User.findOne({ userId: message.author.id })
if (!data) return
message.channel.send(`The nickname is ${nickname}`)
})
you can define the Schema by using
const data = Schema.findOne({ UserID: message.author.id })
const nick = data.nickname;
if (!data) return message.reply({content: 'You have no data'})
message.reply({content: `Your nickname is ${nick}`})
Or you can bring the schema and use .then()
Schema.findOne({ userID: message.author.id }, async (err, data) => {
// your code here
});
Don't forget to add your schema folder path
const Schema = require('...') // your schema file
this way it search for the data in database using the userID because findbyId() is the main mongodb collection id
findById() method finds by _id field. So you can either do this:
client.on("message", msg => {
if (msg.content === "!nickname"){
// reply by User find by _id mongoose
User.findById(id, (err, user) => {
if (err) return console.error(err);
msg.reply(`Your nickname is ${user.nickname}`);
});
}
});
Or do this if you want to query with nickname:
client.on("message", msg => {
if (msg.content === "!nickname"){
// reply by User find by nickname mongoose
User.findOne({nickname: "nickname"}, (err, user) => {
if (err) return console.log(err);
msg.reply("Your Nickname:", user.nickname);
}
);
}
});
You need to pass the actual Mongo ID into User.findById, if you want to find by userID or nickname write something like
User.find({ nickname })
Related
Accounts model:
let accountsSchema = new mongoose.Schema({
posts:{
type: Array
}
});
const Post = mongoose.model("Account", postSchema);
controller in Posts microservice, which populates the posts array in the Accounts microservice:
let myAccountPosts = await axios.get(`${process.env.ACCOUNTS_MICROSERVICE_URL}/router/account/${userID}`)
.then((resp) => {
resp.data.message.map((account) =>{
account.posts.map((post) =>{
if(myUserPostID !== post._id){
//the following resets the entire posts array in the other microservice, consider resetting/deleting only that particular post
let deletePostFromAccountsMicroservice = axios.patch(`${process.env.ACCOUNTS_MICROSERVICE_URL}/router/account/update/${userID}`, {"posts.$[]": "abc"}, (err) =>{
if(err) return err;
});
}else{
console.log("no")
}
});
});
}).catch((err) =>{
console.log("err: ", err.message);
return err;
});
Now I need to be able to update a single object in the array and not override the whole array.
This is what the response looks like:
{
posts:[{_id:'6290ed85716a08d29dab3aa5'}, { _id: '1234ed85716a08d29b35342' } ]
}
In the following line of code:
let deletePostFromAccountsMicroservice = axios.patch(`${process.env.ACCOUNTS_MICROSERVICE_URL}/router/account/update/${userID}`, {"posts.$[]": "abc"}, (err) =>{
if(err) return err;
});
I want the posts.$[] to target only the
object that has an _id that matches this condition (myUserPostID !== post._id)
How do achieve that?
const pool = require('../db')
const asyncHandler = require('express-async-handler')
const { generateToken } = require('../middleware/userAuth')
// #desc Register New User
// #route POST /api/users/register
// #public Public
const registerUser = asyncHandler(async(req, res) => {
const { email, name, password } = req.body
const newUser = {
name,
email,
password
}
const existingUser = ''
if (existingUser) {
res.status(400)
throw new Error('User Already Exists')
} else {
try {
const result = await pool.query(
'INSERT INTO users (name, email, password) VALUES ($1, $2, $3) RETURNING *',
[name, email, password],
(err, res) => {
if (err) {
console.log(err)
}
}
)
res.status(201)
res.json(result.rows)
} catch (error) {
console.log(error)
res.status(400)
throw new Error('Unable to create user')
}
}
})
I'm trying to figure out how to console.log the errors that come from the postgresql database errors when I make a query.
So far, the try/catch is only catching main errors in express. The console.log(error) will say "Type Error, cannot return rows of undefined" which means "result" variable is undefined because the query failed, and "Unable to create user" from the new Error thrown. (I purposefully made it fail)
The "err" callback doesn't seem to console.log anything.
I'd like to be able to see what specifically in postgresql was the problem, such as in this case the columns do not exist.
Any ideas?
im dealing with a problem i can't solve. I've got 2 tables - 'users' and 'login'. The 'users' table keep all my user's info and the 'login' table keep the user's emails and hashes:
this is my backend code:
const handleRegister = (req, res, db, bcrypt, saltRounds) => {
const { email, first_name, last_name, password } = req.body;
// creating hash for password
const salt = bcrypt.genSaltSync(saltRounds);
const hash = bcrypt.hashSync(password, salt);
// form validation
if ( !email || !first_name || !last_name || !password) {
return res.status(400).json('incorrect form submission');
}
// updating login and users tables in the database
db.transaction(trx => {
trx.insert({
first_name: first_name,
last_name: last_name,
email: email,
joined: new Date()
})
.into('users')
.returning('email')
.then(loginEmail => {
return trx('login')
.returning('email')
.insert ({
hash: hash,
email: loginEmail[0]
})
.then(userEmail => {
db.select('*').from('users').where('email', userEmail[0])
.then(user => {
userInfo = Object.assign(user[0], {lists: []} , {tasks: []});
res.json({user: userInfo});
})
.catch(err => {res.status(400).json('unable to get user')})
})
})
.then(trx.commit)
.catch(trx.rollback)
})
.catch(err => {
res.status(400).json('unable to register');
console.log(err);
})
At first when i try to add new user through postman everything is ok, but when i try to add another user i got an error: "TypeError: Cannot convert undefined or null to object" because for some reason the db.select in line 28 does not get any result and passes user=[]. The thing is that when i check my database - the user that i just added is there. it looks like its doing the db.select in line 28 before the insert in line 23...
thank you for your help.
So as you can see. I am trying to take the previous password in the column and update it with the hashed version. For some reason the save on the document isn't firing right away. So I tried using async await and even creating a custom async await foreach to await the callback and the save. However, Mongoose seems to be waiting for all of the saves to come in before applying the save.
This is the error that I get.
UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 505)
(node:2440)
const User = require("./models/User");
const bcrypt = require("bcryptjs");
const db = require("./config/keys").mongoURI;
async function hashIt(user) {
console.log(user);
bcrypt.genSalt(10, (err, salt) => {
if (err) console.log(err);
bcrypt.hash(user.Password, salt, async (err, hash) => {
if (err) throw err;
user.Password = hash;
const id = await user.save();
console.log(id);
})
});
}
async function asyncForEach(array, callback) {
for (let index = 0; index < array.length; index++) {
await callback(array[index], index, array);
}
}
async function mySeed() {
try {
User.find({}, async (err, users) => {
if (err) console.log(err);
asyncForEach(users, async (user) => {
await hashIt(user);
})
});
} catch (e) {
console.log(e);
}
}
async function fullThing(){
mongoose.connect(db, { useNewUrlParser: true })
.then(async () => {
await mySeed();
console.log("finished successfully");
})
}
fullThing();```
I appreciate the response. The solution turned out to be that w=majority for some reason needed to be removed from the db connection. After removing that. Everything began working fine. Wrapping the connect with the catch did help to find the error.
I have a similar routine running on my current back front end system, and below is how I have adapted your code to mine; mine is working, therefore I hope yours will work as well. I believe the problem is that is you are not catching potential errors, that happened to me a lot in the beginning, and sometimes it still happens when I am tired.
bcrypt.genSalt(10, (err, salt) => {
if (err) console.log(err);
bcrypt.hash(user.Password, salt, (err, hash) => {
if (err) throw err;
user.Password = hash;
const id = user
.save()
.then(() => {
console.log("okay");
})
.catch(err => console.log(err));
});
});
In case it does not work, please, let me know what comes out as error.
Appendix
I have tested my solution below:
const bcrypt = require("bcryptjs");
require("./connection");
//creating user schema
var mongoose = require("mongoose");
var Schema = mongoose.Schema;
UserSchema = new Schema({ name: String, password: String });
var User = mongoose.model("User", UserSchema);
const user = new User({ name: "Jorge Pires", password: "Corona Virus" });
console.log(` Before hashing ${user.password}`);
//---------------------------------------------------------------
//Uncomment here to save the user before hashing, it will change anyway, therefore no need!
// user.save();
// User.create({ name: "Jorge Pires", password: "Corona Virus" });
//--------------------------------------------------------------
bcrypt.genSalt(10, (err, salt) => {
//generates the salta
if (err) console.log(err);
bcrypt.hash(user.password, salt, (err, hash) => {
//creates the hash
if (err) throw err;
user.password = hash; //saves the hash
const id = user
.save()
.then(() => {
console.log(` after hashing ${user.password}`);
console.log(` Here goes the user id ${user.id}`);
})
.catch(err => console.log(err));
});
});
Output sample:
Before hashing Corona Virus
we are connected mongoose-tutorial
after hashing $2a$10$84MqPsiiMGA/KTHKFbytVOD5/su6rXiE7baA2TmsLzPMe.Y45aL9i
Here goes the user id 5e710a0bd4385c05b0cd827f
I am new to Node and Javascript in general and I was wondering if I should validate uniqueness by using FindOne before using .save.
My User schema does have Unique:true set for email and username and my current code works like a charm since mongoose returns an error message for uniques.
I wanted to know if it was better to validate for uniqueness before attempting to save for effiency or something?
Current code as follow :
export const createUser = (data) => {
return new Promise( async (resolve, reject) => {
const userData = JSON.parse(data);
const newUser = new User(userData);
await newUser.save((err) => {
if(err){
const msg = err.errmsg.toLowerCase();
const errormsg = msg.includes('email') ? 'Email already in use' : msg.includes('username') ? 'Username already in use' : 'Unexpected error.'
reject(JSON.stringify({error: errormsg}));
}
resolve(JSON.stringify({status: 200, created: true}));
});
});
};
Implemented here :
public register(req, res){
validateRegisterForm(req.body).then(data => {
createUser(data).then(resp => {
res.send(resp);
}).catch(err => {
res.send(err);
})
}).catch(err => {
res.send(err);
});
}