I'm working on a twitter clone to learn MERN stack, here's a new tweet route
router.route('/new')
.post( (req, res) => {
const { errors, isValid } = validateTweet(req.body);
if (!isValid) {
return res.status(400).json(errors);
}
let tweet = new Tweet({
content: req.body.content,
created_by: req.user.id
})
User.findById(req.user.id, (err, user) => {
if (err) return res.status(400).json(err)
user.tweets.push(tweet._id);
user.save();
});
tweet.save();
return res.status(201).json(tweet);
});
Which does not return timestamps for the tweet, how can i achieve this without querying the database for the tweet before returning it?
Here's the model just in case:
const tweetSchema = new Schema({
content: {
type: String,
required: true,
minlength: 1,
maxlength: 128,
trim: true
},
created_by: {
type: Schema.Types.ObjectId, ref: 'User',
required: true
}
}, {
timestamps: true
});
const Tweet = mongoose.model('Tweet', tweetSchema);
What i ended up doing was making the funcion async then returning the result of the fulfilled save(). Not sure if this is a good practice or not.
router.route('/new')
.post( async (req, res) => {
const { errors, isValid } = validateTweet(req.body);
if (!isValid) {
return res.status(400).json(errors);
}
let tweet = new Tweet({
content: req.body.content,
created_by: req.user.id
})
User.findById(req.user.id, (err, user) => {
if (err) return res.status(400).json(err)
user.tweets.push(tweet._id);
user.save();
});
tweet = await tweet.save();
return res.status(201).json(tweet);
});
Related
I am trying to create a followers/following function in my project. However I cannot seem to update the DB correctly. I'm able to send the ids as they both print when I console.log but nothing in my DB updates and I do not get any response in my frontend.
route
app.put('/api/follow', async function (req, res, next){
const { id } = req.query;
const userFrom = req.body.data
console.log('OTHER USER ID',id)
console.log('CURRENT ID', userFrom)
User.findByIdAndUpdate(id), {
$push:{followers:req.body.data}
},{new:true},
(err,result)=>{
if(err) {
if(err) return res.status(400).send(err)
}
User.findByIdAndUpdate(req.body.data), {
$push:{following:id}
},{new:true}.then(result=> {
res.json(result)
}).catch(err=>{
return res.status(422).json({error:err})
})
}
})
user model
const mongoose = require("mongoose");
const User = mongoose.model(
"User",
new mongoose.Schema({
username: String,
email: String,
password: String,
phoneNo: String,
bio: String,
filePath: String,
following: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "User",
},
],
followers: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
},
})
);
module.exports = User;
my route end function
const clickHandler = () => {
const currentID = currentUser.id;
const id = this.props.id;
console.log('CURRENT ID',currentID)
console.log('otherUserID',id)
Axios.put(`http://localhost:8080/api/follow/?id=${id}`, { data: currentID }, { headers: authHeader() })
.then(response => {
if (response.data.success) {
console.log('FOLLOWED', response.data)
// this.setState({ userDetails: response.data.details })
} else {
alert('Error')
}
})
}
This should be
User.findByIdAndUpdate(id, {
You should not close the bracket after id but after new: true})
when I use this code to try and update the user it appears as a server error. Im using JWT and mongodb but am unsure if im pulling the token or the id to update the users information. Below my controller code is attached and my schema.
const updateUser = async (req, res) => {
try {
const user = await User.findByIdAndUpdate(req.user.id)
if(!user) return res.status(400).send({ error: 'User not found'})
Object.assign(user, req.body);
user.save()
res.send({ data: user})
} catch (error) {
res.status(500).send({error: 'Server Error'})
}
}
const mongoose = require('mongoose');
let userSchema = new mongoose.Schema({
name: { type: String, required: true},
email: { type: String, required: true, unique: true},
password: { type: String, required: true},
date: { type: Date, default: Date.now}
})
module.exports = mongoose.model('user', userSchema)
Updated update function but i appear to have an error
const updateUser = async (req, res) => {
try {
const updatedUser = await User.findByIdAndUpdate(req.params.id,req.body)
if(!updatedUser) return res.status(400).send('User cannot be updated!')
res.json(updatedUser)
} catch (error) {
res.status(500).send({error: 'Server Error'})
}
}
Try this :
//update user by id
exports.updateUser = async (req, res) => {
try {
const updatedUser = await
<--req.params.id is the user.id and req.body contains the requested fields to update -->
User.findByIdAndUpdate(req.params.id,req.body)
res.json(updatedUser);
}
catch (err) {
console.log(err);
res.status(500).json({ message: 'Internal server error' });
}
}
I have created a Mongo DB schema with Mongoose in Express.js and I am building the REST API. However when I try to update existing records the values that I do not update from the schema automatically become null. I understand why this happens just not sure exactly how it should be coded.
This is the route:
router.patch("/:projectId", async (req, res) => {
try {
const updatedProject = await Project.updateOne(
{ _id: req.params.projectId },
{
$set: {
title: req.body.title,
project_alias: req.body.project_alias,
description: req.body.description
}
}
);
res.json(updatedProject);
} catch (err) {
res.json({ message: err });
}
});
also here is the schema:
const ProjectsSchema = mongoose.Schema({
title: {
type: String,
required: true,
unique: true
},
project_alias: {
type: String,
unique: true,
required: true
},
description: String,
allowed_hours: Number,
hours_recorded: {
type: Number,
default: 0
},
date_added: {
type: Date,
default: Date.now
}
});
My problem is that when I want to update just the title:
{
"title" : "Title Updated33"
}
description and alias become null. Should I implement a check?
Just use req.body for the update object like this:
router.patch("/:projectId", async (req, res) => {
try {
const updatedProject = await Project.updateOne(
{ _id: req.params.projectId },
req.body
);
res.json(updatedProject);
} catch (err) {
res.json({ message: err });
}
});
Or even better, create a helper function like this so that we can exclude the fields in the body that doesn't exist in the model:
const filterObj = (obj, ...allowedFields) => {
const newObj = {};
Object.keys(obj).forEach(el => {
if (allowedFields.includes(el)) newObj[el] = obj[el];
});
return newObj;
};
router.patch("/:projectId", async (req, res) => {
const filteredBody = filterObj(
req.body,
"title",
"project_alias",
"description",
"allowed_hours",
"hours_recorded"
);
try {
const updatedProject = await Project.updateOne(
{ _id: req.params.projectId },
filteredBody
);
res.json(updatedProject);
} catch (err) {
res.json({ message: err });
}
});
I working on Mongoose and Express project where by I have 3 models: User, Album and Purchase. The purchase model references the user and album. I am creating a POST endpoint where by I can make a purchase and then retrieve the data as well as the user and album relations which should be populated with their data, but I am stuck.
var app = express();
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
var userSchema = mongoose.Schema({
// TODO: Define Schema
name: {
type: String,
required: true
}
})
var User = mongoose.model('User', userSchema)
var albumSchema = mongoose.Schema({
// TODO: Define Schema
title: {
type: String,
required: true
},
performer: {
type: String,
required: true
},
cost: {
type: Number,
required: true
}
})
var Album = mongoose.model('Album', albumSchema);
var puchaseSchema = mongoose.Schema({
// TODO: Define Schema
user: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Album'
},
album: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
}
})
var Purchase = mongoose.model('Purchase', puchaseSchema);
app.use(bodyParser.json());
app.listen(3000);
// TODO: GET /albums
app.get('/albums', (req,res) => {
Album.find()
.then((response) => {
res.json({data: response})
})
.catch(err => {
res.json({error: err})
})
})
// TODO: GET /albums/:id
app.get('/albums/:id', (req,res) => {
Album.findById(req.params.id)
.then(response => {
res.json({data: response})
.catch(err => {
res.json({Error: err})
})
})
})
// TODO: POST /albums
app.post('/albums', (req,res) => {
const newPost = Album({
title: req.body.title,
performer: req.body.performer,
cost: req.body.cost
})
newPost.save(err => {
if(err)
res.json({error: err})
})
.then(data => {
res.json({data: data})
})
})
// TODO: PUT /albums/:id
app.put('/albums/:id', (req,res) => {
Album.findByIdAndUpdate(req.params.id, req.body, {new: true},
(err, album) =>{
if(err) return res.status(500).send(err)
return res.json({data: album})
})
})
// TODO: DELETE /albums/:id
app.delete('/albums/:id', (req,res) => {
const id = req.params.id
Album.findById(id)
.then(docs => {
docs.remove()
res.status(204)
.json({data:docs})
})
})
// TODO: POST /purchases
app.post('/purchases', (req,res) => {
})```
This might help you. Look into mongoose's populate method.
app.post('/purchases', (req,res) => {
const user = req.body.userId;
const album = req.body.albumId;
const newPurchase = new Purchase({
user: user,
album: album
});
newPurchase.save().then((purchase) => {
Purchase.findById(purchase.id).populate('user').populate('album').then((purchaseData) => {
return res.json({purchaseData});
}).catch(e => {
console.log(e);
});
}).catch(e => {
console.log(e);
});
})
Here's an alternative for populating after saving the document.
app.post('/purchases', (req,res) => {
const user = req.body.userId;
const album = req.body.albumId;
const newPurchase = new Purchase({
user: user,
album: album
});
newPurchase.save().then((purchase) => {
Purchase.populate(purchase, [{path: 'user'}, {path: 'album'}], (err, data) => {
if(err) {
return res.json(e);
}
return res.json(data);
});
}).catch(e => {
console.log(e);
});
}
)
As mentioned here: https://mongoosejs.com/docs/api.html#model_Model.populate
I'm learning to use Node.js and MongoDB. I have a problem when I try to save data to the database.
Here's my code
const Test = require('../models/test');
const test = (req, res, next) => {
let url = "http://localhost:3000/article"
request(url, (req, (err, fields) => {
if (err) {
return res.status(400).json({
error: "error"
})
}
var objTest = JSON.parse(fields.body);
console.log(objTest.user)
let test = new Test(objTest)
console.log("ini",test)
test
.save()
.then(result => {
res.send(result)
})
.catch(err => {
console.log(err);
res.status(500).json({
error: err
});
});
}))
}
here my Test Schema
const testSchema = new mongoose.Schema(
{
tittle: {
type: String,
index: true,
},
content: {
type: String,
},
postedBy: { type: mongoose.Schema.ObjectId, ref: 'Author' },
created: {
type: Date,
default: Date.now,
},
},
{
timestamps: true,
},
);
module.exports = mongoose.model('Test', testSchema, 'tests');
The response in Postman is only id, createdAt and updatedAt. Thank you.