Read object value in Nestjs problems - nestjs

I faced with problem to read object in Nestjs
There is the code
#Post()
#UseInterceptors(
FileInterceptor('file', {
storage: diskStorage({
destination: (req, file, cb) => {
const userId = req.body.username;
const usern = req.user;
console.log(usern);
const dir = `./public/avatar/${userId}`;
fs.exists(dir, (exist) => {
if (!exist) {
return fs.mkdir(dir, (error) => cb(error, dir));
}
return cb(null, dir);
});
console.log(usern) return
{
_id: '6026654c957fe6330a6d54c2',
status: 'active',
iat: 1615467122,
exp: 1615553522
}
But If i try to get req.user._id an error is appear
error TS2339: Property '_id' does not exist on type 'User'.

Looks like a TypeScript error, your User class appears not to have the attribute _id. you should add the attribute in the class.

Related

Cannot read properties of undefined (reading 'path')

route file
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './uploads');
},
filename: function (req, file, cb) {
cb(null, new Date().toISOString() + file.originalname);
},
});
const fileFilter = (req, file, cb) => {
// reject a file
if (file.mimetype === 'image/jpg' || file.mimetype === 'image/png') {
cb(null, true);
} else {
cb(null, false);
}
};
const upload = multer({
storage: storage,
limits: {
fileSize: 1024 * 1024 * 5,
},
fileFilter: fileFilter,
});
router.post('/hiring', upload.single('resume'), (req, res, next) => {
console.log(req.file);
const hiring = new Hiring({
_id: new mongoose.Types.ObjectId(),
username: req.body.username,
email: req.body.gender,
mobile: req.body.mobile,
resume: req.file.path,
});
hiring
.save()
.then((result) => {
console.log(result);
res.status(200).json({
message: 'Created user successfully',
createdUser: {
_id: result._id,
username: result.username,
email: result.email,
mobile: result.mobile,
resume: result.resume,
},
});
})
.catch((err) => {
console.log(err);
res.status(500).json({
error: err,
});
});
});
I am trying to post data in database through postman but it is getting error 'path undefined'. I tried to change folder path like './uploads/', '/uploads', 'uploads/' and 'uploads' but the problem is not solving.
error
TypeError: Cannot read properties of undefined (reading 'path')
please give the solution for this problem.
It appears req.file is undefined. which itself meant you are not uploading file via postman.
You have to attach file in postman with 'resume' as keyword after selecting mutlipart in body section.
check this screenshot
With dothttp
It would look like this
POST 'http://localhost:3000/hiring'
multipart(
'resume'< '<replace path to the resume here>',
)

not updating if file is not selected in nodejs using multer

I am trying to update the data. It's working fine if I select the file but there is a problem when I just want to update any field excluding file input type. I am not able to update in such a condition.
How can I resolve it?
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './public/uploads/')
},
filename: function (req, file, cb) {
cb(null, file.originalname+Date.now()+path.extname(file.originalname))
}
});
var upload = multer({
storage:storage,
});
app.post('/editProfile', auth, upload.single('image'), async (req, res, next) => {
try {
const userEmail = req.user.email;
const name = req.body.name;
const filename = req.file.filename;
const contact = req.body.contact;
console.log(filename + "fghj");
if(filename) {
const edited = await User.updateOne({ 'email': userEmail }, {
$set: {
name: name,
contact: contact,
filename:filename
}
});
}
else {
const edited = await User.updateOne({ 'email': userEmail }, {
$set: {
name: name,
contact: contact,
}
});
}
res.redirect('profile');
}
catch (e) {
console.log(`while edit profile ${e}`);
res.status(400).send(e);
}
})
You are trying to get filename but remember you didn't send a file in your scenario. Here:
const filename = req.file.filename;
First, you should check if a file is exist or not.
You can revise your code like this:
app.post('/editProfile', auth, upload.single('image'), async (req, res, next) => {
try {
const userEmail = req.user.email;
const name = req.body.name;
// const filename = req.file.filename; Remove this line from here
const contact = req.body.contact;
if (req.file) {
const filename = req.file.filename // And, use that code when you make sure that you have a file
const edited = await User.updateOne({ 'email': userEmail }, {
$set: {
name: name,
contact: contact,
filename: filename
}
});
}
else {
const edited = await User.updateOne({ 'email': userEmail }, {
$set: {
name: name,
contact: contact,
}
});
}
res.redirect('profile');
}
catch (e) {
console.log(`while edit profile ${e}`);
res.status(400).send(e);
}
})

How can i if dont send image implement default image on my user?

Hi everyone My users have profile picture but its not required,I dont want. So I need if user send me image while register or updated i take this picture and save, so i can this. My problem if user dont send me image i cant give default image
Its my controller code :
//User Register Controller
const register = async (req, res, next) => {
try {
const {
name,
surname,
username,
phoneNumber,
email,
password,
gender,
profilPicture,
birtDate,
} = req.body;
bcrypt.hash(password, 8, async (err, hash) => {
try {
const user = new User({
name,
surname,
username,
phoneNumber,
email,
password: hash,
gender,
profilPicture: 'http://localhost:4000/' + req.file.path || 'http://localhost:4000/public/images/profilePictures/defaultProfilePicture.png',
birtDate,
});
const createdUser = await user.save();
const token = await createToken(createdUser);
res.status(200).json({ token });
} catch (err) {
res.json(err);
}
});
} catch (error) {
res.json({ message: error.message });
}
};
It's my middleware multer :
const multer = require('multer');
const stor = multer.diskStorage({
destination:function(req,file,cb) {
cb(null,'./public/images/profilePictures')
},
filename:function(req,file,cb){
cb(null,'profilePicture-'+new Date().toISOString().replace(/:/g, '-')+file.originalname);
}
})
const fileFilter = (req, file, cb) => {
if (file.mimetype === 'image/jpeg' || file.mimetype === 'image/png') {
cb(null, true);
} else {
cb(null, false);
}
};
const upload = multer({
storage: stor,
limits: {
fileSize: 1024 * 1024 * 5,
},
fileFilter: fileFilter,
});
module.exports = upload;
My route :
router.post('/register', upload.single('profilPicture'), userController.register);
One way you could do it is set a default within your model
const mongoose = require("mongoose")
const UserSchema = new mongoose.Schema({
profilePicture: {
type: String,
default: 'defaultProfilePicture.png'
}
})
module.exports = mongoose.model("Users", UserSchema)
This way if the user didnt upload a profile picture it would be set to defaultProfilePicture.png
You wouldnt need
profilPicture: 'http://localhost:4000/' + req.file.path || 'http://localhost:4000/public/images/profilePictures/defaultProfilePicture.png',
Just
profilPicture: 'req.file.path'
saving the full URL is never a good idea because you might choose to change it in the future like to remote file store or host your project then the URL will no longer be http://localhost:4000/. You'd ideally save the images unique name and extension.
just try like this :
profilPicture: (req.file) ? 'http://localhost:4000/' + req.file.path : 'http://localhost:4000/public/images/profilePictures/defaultProfilePicture.png';

How to put image into mongodb using node js

I want to put a profile image into the users collection in mongodb, and I'd like to retrieve this image when user fetch his profile.
var storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'uploads/')
},
filename: (req, file, cb) => {
cb(null, file.fieldname + '-' + Date.now()+ path.extname(file.originalname));
}
});
var upload = multer({ storage: storage });
router.put('/user/profile/img/:email', upload.single('profileimg'), (req, res, next) => {
// console.log(req.file);
Users.findOneAndUpdate({ email: req.params.email }, req.file.filename).then(() => {
Users.findOne({ email: req.params.email }).then((resp, err) => {
res.send(resp);
})
})
})
Image is being saved in upload folder in my api but it's not saved in db.
The second parameter of the findOneAndUpdate function must be an object with the field to update and the value:
Users.findOneAndUpdate({ email: req.params.email }, { profileimg: req.file.filename }).then(...)
You can do it like this code below:
router.put('/user/profile/img/:email', upload.single('profileimg'), async (req, res, next) => {
try {
// check your file is uploaded
// check your field
console.log(req.file);
const result = await Users.findOneAndUpdate({ email: req.params.email }, {$set: { profileimage : req.file.filename}}, { returnOriginal: false})
res.send(result)
} catch(ex) {
res.status(500).send(ex.message);
}
})
Note: For this {$set: { profileimage : req.file.filename}}
profileimage : change with the field in your mongodb
req.file.filename: make sure to console.log(req.file) then, where the field you want to store, use it in here and change this example.
I hope it can help you.

Cannot read property of undefined error in mongoose method

I am using node for requesting data using tokens for authentication but getting an error
Error 500 : Cannot read property of undefined
Here is my code
Function findByToken()
var User = this;
var decoded;
try {
jwt.verify(token, 'abc');
} catch(e) {
return Promise.reject();
}
return User.findOne({
'_id': decoded._id,
'tokens.token': token,
'tokens.access': 'auth'
});
This function takes token as an argument and find the data into database.
Route
app.get('/users/me', (req,res) => {
var token = req.header('x-auth');
User.findByToken(token).then((user) => {
res.send(req.user);
}).catch((e) => {
res.send(e);
});
});
This is the route where i am using my function to return the data. But getting a 500 error please help me with this.
You should use statics methods
For example:
animalSchema.statics.findByName = function(name, cb) {
return this.find({ name: new RegExp(name, 'i') }, cb);
};

Resources