Nodejs and Mongoose data fetching - javascript

I have some problem with data fetching.
I have mongoose scheme.
PostSchema.methods.getAuthor = function () {
this.model('User').findById(this.author).exec(function (err, author){
if (author) {
console.log(author.username);
return author.username;
};
});
};
mongoose.model('Post', PostSchema);
and getMethod
exports.getPost = function (req, res) {
return Post.findById(req.params.id, function (err, post) {
if (!post) {
res.statusCode = 404;
return res.send({ error: 'Not found' });
}
if (!err) {
var author = post.getAuthor();
console.log('author is: ', author);
return res.send({ status: 'OK', post:post });
} else {
res.statusCode = 500;
return res.send({ error: 'Server error' });
}
});
};
When I call post.getAuthor() inside getPost method he is work and found User by Id. But var author = post.getAuthor(); have undefined value.

As #zaynetro mentioned you're calling your getAuthor method incorrectly. It's an asynchronous method, so you should be accepting a callback parameter, or you could return a promise.
But what you're trying to do is already built in to mongoose, its called query population.
http://mongoosejs.com/docs/populate.html
You can configure a Post.author reference property that you can have mongoose resolve into the document for you.
var postSchema = Schema({
author: {
type: Schema.Types.ObjectId,
ref: 'User'
}
});
mongoose.model('Post', postSchema);
var userSchma = Schema({
name: String
});
mongoose.model('User', userSchema);
Then, in your route your query would look like this:
Post
.findById(req.params.id)
.populate('author')
.exec(function(err, post) {
if (err) {
return res.status(500).send({
error: 'Server error'
});
}
// post.author contains the content of your author document
return res.send(post);
});

Related

Node Js: Remove string array element from mongoDB

I have a user schema as follows:
const UserSchema = new mongoose.Schema({
skills: [String]
});
module.exports = mongoose.model("User", UserSchema);
And a Fetch request to delete a skill as follows:
const deleteItem = async (id) => {
try {
await fetch(`http://localhost:5000/api/user/deleteskill`, {
method: "DELETE",
headers: { "Content-Type": "application/JSON", token: accessToken },
body: JSON.stringify({ userid: userid , skill:id}),
})
.then((res) => res.json())
.then((data) => {
console.log("USER SKILLS:", data.userskills);
});
} catch (err) {
console.log(err);
}
};
Server
const deleteSkill = async (req, res) => {
try {
const user = await User.findById(req.body.userid)
//user.skills.pull(req.body.skill);
// removeskill = user.skills.filter(function(item) {
// return item !== req.body.skill
// })
if (user.skills.includes(req.body.skill)) {
res.status(400).json("Item Still Exists");
} else {
res.status(200).json("Item Deleted");
}
} catch (error) {
res.status(500).send({ error: error.message });
}
};
the array is in the following structure
[
'skill1', 'java', 'skill5'
]
I have tried to remove the user skill from the array in several ways but I still get res.status(400).json("Item Still Exists");. What I'm doing wrong?
Use the findOneAndUpdate method to find a document with the user id and update it in one atomic operation:
const deleteSkill = async (req, res) => {
try {
let message = "Item Deleted";
let status = 200;
const user = await User.findOneAndUpdate(
{ _id: req.body.userid },
{ $pull: { skills: req.body.skill } },
{ new: true }
)
if (user && user.skills.includes(req.body.skill)) {
message = "Item Still Exists";
status = 400;
} else if (!user) {
message = "User Not Found";
status = 404;
}
res.status(status).send({ message });
} catch (error) {
res.status(500).send({ error: error.message });
}
};
I believe you want to remove skills from the database then the following function could help you out.
var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/";
MongoClient.connect(url, function(err, db) {
if (err) throw err;
var dbo = db.db("mydb");
var myquery = { userid: userid, skillid: skillid};
dbo.collection("skills").deleteOne(myquery, function(err, obj) {
if (err) throw err;
console.log("1 document deleted");
db.close();
});
});
You have a method of removing elements from arrays, if you want to remove the first one you could use array.shift (more on it here), but if you want to delete it completely from your database you could always, find it and then update it.
User.update({ _id: userid }, { $pull: { "skills": "[skill]" }})

Mongoose send requested to nested schema

I don't quite understand why my requests are not added to my DB. I have schema with nested objects. So I try to send requst to specific object inside of an object. Result says scucces, however nothing is added.
Here's schema:
const personSchema = new mongoose.Schema({
connections: {
parents: {type : Array},
children: {type : Array}
}
})
Here's router:
router.patch('/v2/:id', getPerson, async (req, res) => {
if (req.body.connections != null) {
if (req.body.connections.parents != null) { res.person.connections.parents.push(req.body.connections.parents); }
if (req.body.connections.children != null) { res.person.connections.children.push(req.body.connections.children); }
}
try {
const updatePerson = await res.person.save();
res.status(200).json({ message: 'Success' })
} catch (error) {
res.status(400).json({ message: error.message })
}
})
Here's middelware:
async function getPerson(req, res, next) {
let person;
try {
person = await Person.findById(req.params.id);
if (person === null) {
return res.status(404).json({ message: 'Cannot find the person' });
}
} catch (error) {
return res.status(500).json({ message: error.message });
}
res.person = person;
next();
}
Here's request:
PATCH http://localhost:3100/api-db/v2/62e28682cecc9120c7af9de5
Content-Type: application/json
{
"connections.parents" : "test"
}
Connection is established, document in db is alredy created.
It seems to me that I might doing wrong requst. I couldn't find information about nested requsts though.
What seems to be the problem?
P.S.
Other requsts that are not nested are satisfied...
Nvm, I am just retarded:
{
"connections" : {"parents" : "test"}
}

Error in updating profile with image using mongoose and cloudinary

updateProfile: async function(req, res) {
try {
const update = req.body;
const id = req.params.id;
if (!req.files || Object.keys(req.files).length === 0) {
return res.status(400).send('No files were uploaded.');
}
const image = req.files.profileImage;
const cloudFile = await upload(image.tempFilePath);
const profileImage = cloudFile.url
console.log('Loging cloudfile', profileImage)
await User.updateOne(id, { update }, { profileImage }, { new: true },
function(err, doc) {
if (err) {
console.log(err)
}
if (doc) {
return res.status(200).send({ sucess: true, msg: 'Profile updated successful' })
}
});
} catch (error) {
res.status(500).json({ msg: error.message });
}
}
But I'm getting an error of "Callback must be a function, got [object Object]"
I have tried to $set: update and $set: profileImage but still not working.
So the image successful upload into the cloudinary but the update for mongoose is not working.
Upon brief research into the issue, I think you are feeding the arguments in wrong. Objects can be confusing but not to worry.
Your code is:
await User.updateOne(id, { update }, { profileImage }, { new: true }
However, I believe it should be something more like:
await User.updateOne({id: id}, { profileImagine: profileImage, new: true },
The API reference annotates use of the function as:
const filter = { name: 'John Doe' };
const update = { age: 30 };
const oldDocument = await User.updateOne(filter, update);
oldDocument.n; // Number of documents matched
oldDocument.nModified; // Number of documents modified

How to retrieve the mongodb query result from a promise?

I am trying to retrieve the result of a db.collection query in the "/read/:id" route. When a user is found,the promise is fulfilled and status 'success' is sent. The data object is, however, empty.
Query:
const getDb = require('./connection').getDb,
ObjectId = require('mongodb').ObjectId;
readUser: async function(data) {
let o_id = new ObjectId(data);
await getDb().collection('users').find({ _id: o_id })
}
Route:
const express = require('express'),
router = express.Router(),
queries = require('../db/queries');
router.get('/read/:id', (req, res) => {
queries.readUser(req.params.id)
.then((user) => {
res.status(200).json({
status: 'success',
data: user
})
})
.catch((err) => {
res.status(500).json({
status: 'error',
data: err
});
});
})
res.json
{
"status" : "success"
}
Could anybody explain how to successfully retrieve the data of the query?
Please find the project code here.
Thank you.
Alright, I found a solution.
readUser: async function(data) {
let o_id = new ObjectId(data),
cursor = getDb().collection('users').find({ _id: o_id });
return await cursor.next() // returns document result of collection.find() method
}

unhandled promise rejection warning - couldn't store into database

Data comming from req is store in Comment collection but it is not store in Product collection and i'll get an error message
app.post("/products/:id/comments", function(req, res) {
//lookup campground using ID
Product.findById(req.params.id, function(err, product) {
if (err) {
console.log(err);
res.redirect("/products");
} else {
Comment.create(req.body.comment, function(err, comment) {
if (err) {
console.log(err);
} else {
console.log("aaaaaa");
product.comments.push(comment);
console.log("bbbbbb");
product.save();
console.log("cccccc");
res.redirect('/products/' + product._id);
}
});
}
});});
and following is Product
var mongoose = require("mongoose"),
productSchema = new mongoose.Schema({
name: String,
img: String,
price: Number,
desc: String,
comments: [{
type: mongoose.Schema.Types.ObjectId,
ref: "Comment"
}],
created: {
type: Date,
default: Date.now()
}});module.exports = mongoose.model("Product", productSchema);
and this is Comment Schema
var mongoose = require("mongoose"),
commentSchema = mongoose.Schema({
text: String,
author: String
});module.exports = mongoose.model("Comment", commentSchema);
and i got following output :-
enter image description here
so it's store in commentSchema but it's not store in product.comments and when i run site that also redirect to products/:id, what i'm missing to store comment into database ??
If you don’t pass a callback function to save() then it will return a promise.
Therefore, you are getting the error as you have not added a catch.
Try passing a callback to save():
// ...
product.save(function(err, result) {
if (err) {
// Handle error
}
console.log("cccccc");
res.redirect('/products/' + product._id);
})

Categories

Resources