app.post("/article/add", function(req, res) {
let article = new Article();
article.title = req.body.title;
article.author = req.body.author;
article.body = req.body.body;
article.save(function(err) {
if (err) {
console.log(err);
return;
} else {
res.redirect("/");
}
});
});
How can I change this and add articles in a similar way. I mean I cant create other ways to make it but I know there are lots of ways to post articles.
If you mean, how to refactor your code in a better way, I would suggest these:
1-) use destructuring to parse req.body like this:
app.post("/article/add", function(req, res) {
const { title, author, body } = req.body;
let article = new Article({ title, author, body });
article.save(function(err) {
if (err) {
console.log(err);
return;
} else {
res.redirect("/");
}
});
});
2-) use async await syntax:
app.post("/article/add", async function(req, res) {
const { title, author, body } = req.body;
let article = new Article({ title, author, body });
try {
article = await article.save();
res.redirect("/");
} catch (err) {
console.log(err);
return;
}
});
Related
Quick question: how can I sort my posts data by date?
router.get('/', async (req, res) => {
try {
const posts = await Post.find()
res.json(posts)
}
catch (err) {
res.json({message: err})
}
})
I came from Django and there you could do something like:
posts = Post.objects.filter().order_by('date')
I'm fairly new to NodeJS and Express. Thanks a lot!
It depends on the what the data structure of the date property is. If they are in JS timestamp format:-
router.get('/', async (req, res) => {
try {
const posts = await Post.find();
const sortedPosts = posts.sort((a,b) => {
return new Date(b.date) - new Date(a.date);
});
res.json(sortedPosts)
}
catch (err) {
res.json({message: err})
}
})
Here I've used the array's sort() method. Learn more
I am trying to get the ID of the document that I just inserted into mongoDB. Here is the node.js code:
app.post("/groups/new", (req, res) => {
const dbGroup = req.body;
Groups.create(dbGroup, (err) => {
if (err) {
res.status(500).send(err);
} else {
var id = dbGroup._id;
res.status(201).send(id);
}
});
});
I have tried various things, like adding a group to the function:
app.post("/groups/new", (req, res) => {
const dbGroup = req.body;
Groups.create(dbGroup, (err, group) => {
if (err) {
res.status(500).send(err);
} else {
var id = group._id;
res.status(201).send(id);
}
});
});
But that also does not work, so I tested if my even get the API response on the front end with:
res.status(201).send("test");
Which works perfectly fine. So I don't know why this doesn't work, because all the documentation says this is the way.
I figured a way to get the id. It may be not the most efficient way, because it sends all the data it gets but it gets the job done.
Backend:
app.post("/groups/new", (req, res) => {
const dbGroup = req.body;
Groups.create(dbGroup, (err, data) => {
if (err) {
res.status(500).send(err);
} else {
res.status(201).send(data);
}
});
});
Front end:
axios.post("/groups/new", {
groupname: roomName,
}).then((res) => {
roomid = res.data._id;
});
I have a NodeJS app using Express and Mongoose. I am trying to write a POST route so that when a POST request to the URL is made (currently /api/v1/forms/:formId) then it will set the variable to the recipient`value from the MongoDB database. The :formID will match the _id in MongoDB.
So far I have:
app.post("/api/v1/forms/:formId", async (req, res) => {
//TODO: Create Mailer and email templates before finalising route.
const { _name, _email, _message } = req.body;
const form = Form({
name = req.body._name,
email = req.body._email,
message = req.body._message,
recipient = Form.findById(req.params.form_id, function(err, form) {
if (err)
res.send(err);
})
});
const mailer = new Mailer(form, contactFormTemplate(form));
try {
await mailer.send();
} catch (err) {
res.status(422).send(err);
}
});
I know this is not correct for the recipient field but this is what I could think of off the top of my head
Following what you did, you can do this:
app.post("/api/v1/forms/:formId", async (req, res) => {
//TODO: Create Mailer and email templates before finalising route.
const { _name, _email, _message } = req.body;
let recipient;
try{
recipient = await Form.findById(req.params.form_id).exec();
} catch(err){
res.status(422).send(err);
}
const form = Form({
name: req.body._name,
email: req.body._email,
message: req.body._message,
recipient: recipient
});
const mailer = new Mailer(form, contactFormTemplate(form));
try {
await mailer.send();
} catch (err) {
res.status(422).send(err);
}
});
The .exec() on mongoose return a promise, so it's possible to use async/await syntax.
As far as I understood the problem, here is what I could think of,
Form.findById(req.params.form_id, function(err, form) {
if (err){
res.send(err);
}else{
recipient = form.recipientValue;
}
});
Try this..
app.post("/api/v1/forms/:formId", async (req, res) => {
const { _name, _email, _message } = req.body;
let form;
try {
form = await Form.findById(req.params.formId).select('recipient').exec();
} catch (err) {
res.send(err);
return;
}
const nuForm = Form({
name = req.body._name,
email = req.body._email,
message = req.body._message,
recipient = form.recipient
});
try {
await new Mailer(nuForm, contactFromTemplate(nuForm)).send();
} catch(err) {
res.status(422).send(err);
}
}
My setup is like this:
I get data from omDB using a omdb lib from github, this whole parts looks like this:
router.post('/search', function(req, res) {
var omdb = require('omdb');
var title = req.body.title;
omdb.get( {title: title}, true, function(err, movie){
if(err) {
return console.log(err);
}
if(!movie) {
return console.log('No movie found');
}
//console.log('%s (%d)', movie.title, movie.year);
result = movie.title+movie.year+movie.poster;
console.log(result);
res.redirect('/result');
})
});
And then i want to use the result from that post request in another route:
router.get('/result', function(req, res) {
res.render('result', { title: title});
});
What is the best and hopefully simplest approach to do this, consider that I am a node.js noob.. :)
Assuming you're using express.js, you could use the session middleware:
router.post('/search', function(req, res) {
var omdb = require('omdb');
var title = req.body.title;
omdb.get( {title: title}, true, function(err, movie){
if(err) {
return console.log(err);
}
if(!movie) {
return console.log('No movie found');
}
//console.log('%s (%d)', movie.title, movie.year);
req.session.result = {
title: movie.title,
year: movie.year,
poster: movie.poster
};
res.redirect('/result');
})
});
then:
router.get('/result', function(req, res) {
if (req.session.result) {
var result = req.session.result;
req.session.result = null;
res.render('result', { movie: result });
}
else {
// Redirect to error page.
}
});
I'm a beginner in Node/Express. I tried to make an CRUD application but stuck at update and delete. I think my router code is problematic but I don't know why. The following code is in my controller, everything works but PUT and DELETE. It always route to GET. I tried to use next(); but it returns this error: Can't set headers after they are sent..
I can make the delete works by using GET /:company_id/delete but it's not a good and standardized solution. How can I get update and delete process worked?
'use strict';
var Companies = require('../../models/companies');
module.exports = function (router) {
// INDEX
// accessed at GET http://localhost:8000/companies
router.get('/', function (req, res) {
Companies.find(function(err, model) {
if (err) {
res.send(err);
}
else {
res.format({
json: function () {
res.json(model);
},
html: function () {
res.render('companies/index', model);
}
});
}
});
});
// CREATE VIEW
// accessed at GET http://localhost:8000/companies/create
router.get('/create', function (req, res) {
res.render('companies/create');
});
// CREATE DATA
// accessed at POST http://localhost:8000/companies
router.post('/', function (req, res) {
var name = req.body.name && req.body.name.trim();
var type = req.body.type && req.body.type.trim();
// VALIDATION
if (name === '') {
res.redirect('/companies/create');
return;
}
var model = new Companies({name: name, type: type});
model.save(function(err) {
if (err) {
res.send(err);
}
else {
res.redirect('/companies');
}
});
});
// READ
// accessed at GET http://localhost:8000/companies/:company_id
router.get('/:company_id', function(req, res) {
Companies.findById(req.params.company_id, function(err, model) {
if (err) {
res.send(err);
}
else {
res.render('companies/read', model);
}
});
});
// UPDATE VIEW
// accessed at GET http://localhost:8000/companies/:company_id/edit
router.get('/:company_id/edit', function(req, res) {
Companies.findById(req.params.company_id, function(err, model) {
if (err) {
res.send(err);
}
else {
res.render('companies/edit', model);
}
});
});
// UPDATE DATA
// accessed at PUT http://localhost:8000/companies/:company_id
router.put('/:company_id', function(req, res) {
Companies.findById(req.params.company_id, function(err, model) {
if (err) {
res.send(err);
}
else {
model.name = req.body.name;
model.type = req.body.type;
model.save(function(err) {
if (err) {
res.send(err);
}
else {
res.redirect('/companies');
}
});
}
});
});
// DELETE
// accessed at DELETE http://localhost:8000/companies/:company_id
router.delete('/:company_id', function (req, res) {
Companies.remove({ _id: req.params.company_id }, function(err) {
if (err) {
res.send(err);
}
else {
res.redirect('/companies');
}
});
});
};
HTML forms only support GET and POST. XMLHTTPRequest supports PUT and DELETE however, so you may have to go that route OR use something like method-override to allow HTML forms to submit using other HTTP verbs.