JS file not pulling model.findByPk() using "/:id"? - javascript

I'm trying to pull items from my database using each item's id, but am receiving an empty object when running it through Insomnia. For example, in the code below, I would like to pull a category by ID, but also include any associated Products.
Any idea what I might be doing wrong? Thank you in advance!
router.get('/:id', async (req, res) => {
try {
const oneCategory = await Category.findByPk({
include: [{ model: Product }]
});
// console.log(oneCategory);
if (!oneCategory) {
res.status(404).json({ message: 'No category found with that id!' });
return;
}
res.status(200).json(oneCategory);
} catch (error) {
res.status(500).json(error);
}
});

When calling the findByPk method, you need to pass the key you are looking for. In this particular case, the code should look like this:
router.get('/:id', async (req, res) => {
try {
const oneCategory = await Category.findByPk(req.params.id, {
include: [{ model: Product }]
});
if (!oneCategory) {
res.status(404).json({ message: 'No category found with that id!' });
return;
}
res.status(200).json(oneCategory);
} catch (error) {
res.status(500).json(error);
}
});
So just grab the id from the URL with req.params.id and pass it to findByPk. However, it could be a good idea to check so that the id is in fact an integer before doing so :)

Related

Mongoose - How to Chain Save So Data Can Be Saved to Multiple Collections

I have read all sorts of variations of this on stackoverflow but I cannot seem to find a post that exactly explains what I'm trying to achieve, at the same time I believe this has to be a very common task during saving data.
So I need to save data to one collection and then read the _id from that doc and save it to a doc in a different collection. I have the following code and I can see the correct data with console.log but I don't see the data being saved to the database.
Appreciate if someone can guide me in the right direction.
Thank you!
router.post('/signup', async (req, res) => {
const { email, password, name, country } = req.body;
try {
const user = new User({ email, password });
await user.save((error, doc) => {
if (error) {
console.log(error);
} else {
const userProfile = new UserProfile({ userId: doc._id, name, country });
userProfile.save((error, doc) => {
if (error) {
console.log(error)
} else {
console.log(doc) // Can see this log with the correct data
}
});
}
});
const token = jwt.sign({userId: user._id}, 'MY_KEY');
res.send({ token });
} catch(error) {
return res.status(422).send(error.message)
}
})

How to get data with just inserted data with Sequelize in PostgreSql?

I want to get updated table values after I add user to my "WOD" table. For instance, I have 2 users in my WOD table and after I add third user , I want to return a response to client with I have just inserted data (third guy). But now , I can only return first 2 users because I can not take updated values. Of course I can make another query to get updated table values after I insert, but is there any better solution ? Here is my codes;
const addUser = async (req, res) => {
try {
const { userId, wodId } = req.body;
if (!userId || !wodId) {
res.status(400).send({ status: false, message: 'need userId and wodId' });
}
const wod = await Wod.findByPk(wodId, {
include: [
{
model: User,
as: 'Participants',
through: { attributes: [] }
}
]
});
//check capacity if full.
if (wod.Participants.length >= wod.capacity) {
res
.status(403)
.send({ status: false, message: 'Capacity of this class is full!' });
}
const result = await wod.addParticipants(userId);
res.status(201).json({ status: !!result, wod });
} catch (error) {
res.status(500).send({ status: result, message: error.message });
console.log(error.message);
}
};
As a result of many-to-many association sequelize.sync will generate some functions for us. You are used addParticipants function and this returns an array that added to the assocation(userwod) table.
In this array you will find some id fields(join table fields) because you just run like this INSERT INTO 'user_wods' ('user_id''wod_id') VALUES (2,1). If you want to return the added user's information then you should run a SELECT * FROM 'user' WHERE 'id'=2.
You must call reload function for fetch the third guy.
await wod.reload()

Delete an element from array by update method

I'm trying to delete one element from an array in one of the mongoose schema I made. But the pull method doesn't seem to work well for me
I manage to add an element and I'm trying to make it basically the same but in reverse. But the pull method doesn't seem to work for me.
this is my schema
userName: {type: String, required: true, unique: true},
password: {type: String, required: true},
favorite: [{type: Schema.Types.ObjectId, ref:'programs'}]
and this is how I'm adding an element to the array
router.put('/favorite/:id', (req, res) => {
User.findOne({ _id: req.params.id }, (err, user) => {
if(err) return console.error(err);
user.favorite.push(req.body.favorite);
user.save((err, user) => {
if(err) return console.error(err);
console.log(user);
});
res.json(user);
})
});
here I tried to make it in similar way to remove one element but didn't work, in postman it showed just that it cannot put
router.put('favorite/delete/:id', (req, res) => {
User.findOne({_id: req.params.id}, (err, user) =>{
if(err) return console.error(err);
user.favorite.pull(req.body.favorite);
user.save((err,user) => {
if (err) return console.error(err);
console.log(user);
});
res.json(user);
})
});
Basically, I just need to be able to remove the element by its id. I feel like the id should be mentioned somewhere, but I'm not sure where or how. Thanks for all the tips
I highly recommend using async await insted of callbacks, mongoose supports Promises.
You can also use mongoose queries to update fields instead of JavaScript, this will reduce the amount of queries to the database.
Also when an error occurs don't forget to send a response to the user to inform that something went wrong.
You tried to use MongoDB $pull operator in JavaScript instead of using it in the query, you cant use MongoDB operators in JavaScript
You can also destructure properties from req.params to make it more readable
Note the id have to be the user document id and favorite have to be the favorite document id
Now you can add to favorites using $push
// to use the await keyword we have to set the callback to an async function
router.put('/favorite/:id', async (req, res) => {
// destruct id from the req.params object and favorite from req.body
const { id } = req.params;
const { favorite } = req.body;
try {
const updatedUser = await User.findByIdAndUpdate(id,
{ $push: { favorites: favorite } },
// new: true means return the updated document
{ new: true },
);
res.send(updatedUser);
} catch (e) {
console.error(e);
res.status(500).send('Something went wrong');
}
});
And remove from favorites using $pull
router.put('/favorite/delete/:id', async (req, res) => {
const { id } = req.params;
const { favorite } = req.body;
try {
const updatedUser = await User.findByIdAndUpdate(id,
{ $pull: { favorites: favorite } },
{ new: true },
);
res.send(updatedUser);
} catch (e) {
console.error(e);
res.status(500).send('Something went wrong');
}
});

Processing a database query in Javascript

I'm using Express and Handlebars to display a value set by the user and stored in the database.
Handlebars is set up to display the value "{{userMotto}}".
Express does the following:
function isUserAuthenticated(req, res, next) {
if (!req.user) {
res.render('index', {
user: req.user
});
} else {
currentUser = req.user.username;
userMottoCaught = queryDatabase("motto", currentUser);
next();
}
}
I want it to set the value of "userMottoCaught" to whatever it finds in the database. The query itself is this:
function queryDatabase(dbCollection, dbUID) {
this.dbCollection = dbCollection;
this.dbUID = dbUID;
return MongoClient.connectAsync(hiddenkeys.mongodbUri)
.then(function(db) {
return db.collection(dbCollection).findOneAsync({
_id: dbUID
});
})
.then(function(item) {
console.log("Found: ");
console.log(item);
return dbQueryResult;
})
.catch(function(err) {
//err
});
}
The problem is that I cannot for the life of me get the dbQueryResult out and return it to function queryDatabase itself. Probably because it's being returned to a sub function right now instead of the main function, I think. I highly suspect this can be easily resolved but I'm just at a loss on how to fix this. I am using Bluebird here to see if I could solve this with promises, but I'm not sure this is the right route either. I've also looked into callbacks but I cannot for the life of me figure out how to apply either concept to my code to solve my problem.
Later on when I render the page I do this to render it on the page:
router.get('/', isUserAuthenticated, function(req, res) {
res.render('dashboard', {
user: req.user,
userMotto: userMottoCaught
});
});
Currently this yields on the page: "Motto: [object Promise]", because I haven't returned the proper value to the main function.
Is there anyone out there with some wise words?
Cheers,
Dean
i think you need to make a callback here
function isUserAuthenticated(req, res, next) {
if (!req.user) {
res.render('index', {
user: req.user
});
} else {
currentUser = req.user.username;
userMottoCaught = queryDatabase("motto", currentUser,function(err,data){
userMottoCaught = data
next();
});
}
}
and the definition of queryDatabase should look like
function queryDatabase(dbCollection, dbUID,cb) {
this.dbCollection = dbCollection;
this.dbUID = dbUID;
return MongoClient.connectAsync(hiddenkeys.mongodbUri)
.then(function(db) {
return db.collection(dbCollection).findOneAsync({
_id: dbUID
});
})
.then(function(item) {
console.log("Found: ");
console.log(item);
dbQueryResult = JSON.stringify(item.motto);
cb(null,dbQueryResult)
})
.catch(function(err) {
//err
cb(err);
});
}

mongoose "Find" with multiple conditions

I am trying to get data from my mongoDB database by using mongoose filters. The scenario is that each user object in the database has certain fields like "Region" or "Sector".
Currently I am getting all the users that contain the keyword "region" in there object like so:
// Filter all healthcare bios by region
app.get('/user',function(req, res) {
// use mongoose to get all users in the database
User.find({region: "NA"}, function(err, user)
{
// if there is an error retrieving, send the error. nothing after res.send(err) will execute
if (err)
{
res.send(err);
}
// return all todos in JSON format
console.log(user);
res.json(user);
});
});
How can put some conditions in mongoose that it return users that contain both "region" && "Sector" in their objects. Currently its only returning the user which have the region keyword in them.
I have tried using $and operator but I couldn't get it to work.
app.get('/user',function(req, res) {
User.find({region: "NA",sector:"Some Sector"}, function(err, user)
{
if (err)
{
res.send(err);
}
console.log(user);
res.json(user);
});
});
If you want data with either region:"NA" or sector:"Some Sector". you can use $or operator.
User.find({$or:[{region: "NA"},{sector:"Some Sector"}]}, function(err, user)
{
if (err)
{
res.send(err);
}
console.log(user);
res.json(user);
});
If you want results that contain any region or sector as long as both are present at the same time you need the following query in your User.find:
{region: {$exists:true},sector: {$exists:true}}
, is the equivalent of $and as long as you are searching different fields.
const dateBetweenDates = await Model.find({
$or: [
{
$and: [
{ From: { $gte: DateFrom } },
{ To: { $lte: DateTo } },
], // and operator body finishes
},
{ _id: req.user.id},
], //Or operator body finishes
})
For anyone else trying to find with multiple conditions using mongoose, here is the code using async/await.
app.get('/user', async (req, res) {
const user = await User.find({region: "NA",sector:"Some Sector"});
if (user) {
// DO YOUR THING
}
});

Categories

Resources