I saw some problems which are close to mine but not exactly the same so my issue is I got a ejs template with a Form attribut and I want to send the input to a mail so I declare all input with name="xyz" and inside the routes.get: req.body.conSurname, conName: req.body.conName,. So my post route looks like this.
router.post('/contact/send', (req, res) => {
// Nodemailer
let transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: 'abc#gmail.com',
pass: '******'
}
});
const mailOptions = {
from: 'abc#gmail.com',
to: 'def#gmx.de',
subject: 'New Mail',
html: '<h2>Mail from: '+ req.body.conSurname + ' ' + conName + '</h2>'
};
transporter.sendMail(mailOptions, function (err, info) {
if (err)
console.log(err)
else
console.log(info);
});
res.redirect('/contact');
})
If I send the formular it throws ReferenceError: conSurname is not defined but if I log one attrubut it shows me the correct value from the input.
Where is the error?
That's because you have to import the json middleware like this:
var express = require('express');
var app = express();
app.use(express.json());
Then your express server will deserialize JSON bodies when receiving requests with the Content-Type: application/json header, and your code will work correctly.
Related
I am creating a rest api service to get, put, delete data from odoo erp .
Here is my code :
const Promise = require('bluebird');
Promise.promisifyAll(require('node-odoo').prototype);
const Odoo = require('odoo-xmlrpc');
const odoo = new Odoo({
url: 'zzzz',
port: 'zz',
db: 'zzzz',
username: 'zzzz',
password: 'zzz*'
});
var express = require('express'),
app = express(),
port = process.env.PORT || 3000;
this.router = express.Router();
app.listen(port);
console.log('todo list RESTful API server started on: ' + port);
this.router.get('/api/event/', (req, res) => {
return getEvent(req, res);
});
app.get('/getEvent', (request, response) => {
odoo.connect((err) => {
if(err) return console.log('Findeventlist error ' + err);
console.log('Findeventlist connected ' );
var inParams = [];
inParams.push([]);
inParams.push(['name' ])
inParams.push(0)
inParams.push(5)
var params = [];
params.push(inParams);
odoo.execute_kw('calendar.event', 'search_read', params, function (err, value) {
if (err) { return console.log(err) }
if(value){
console.log( 'Value is ' + response.status(200).json(value));
return response.status(200).json(value)
}
});
});
console.log(' odoo connected');
})
I got this error : Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
Can you help me please where i'm wrong?
response.status(200).json(value) responds to the client and ends the transaction (just like response.end() or response.sendFile() etc).
It must be called only once, but you execute it twice (once inside the console.log() then once "for real" the next line). That's why the headers are "already sent".
Remove the useless response.json() from the console.log and log only the value you want to see.
I'm trying to build an API that receives a POST req to create a user but I am getting undefined errors for all of my req.body requests. My app is set up like this (simplified for brevity):
User controller that gets called by Express Router in my user routes file
/controllers/user.js
userController.addUser = function(req, res) {
let user = new User();
user.username = req.body.username;
user.first_name = req.body.first_name;
user.last_name = req.body.last_name;
user.email = req.body.email;
user.type = req.body.user_type
// This returns undefined as does all other req.body keys
console.log("REQ.BODY.EMAIL IS: " + req.body.email);
}
User Route File:
/routes/user.js - requires user controller above
router.post('/user/create', userController.addUser);
Main App:
all routes and controllers work per my tests except where req.body.* is used
index.js - main app file
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use('/api', routes);
I have looked through the Express documentation and through countless StackOverflow posts with no luck. Let me know if you need further clarification.
My issue was how I was sending the body to the API endpoint. I was using form-data instead of x-www-form-urlencoded with Postman. User error
Sometime with change in version body-parser seems to not work, in that case just use following, this will remove dependency from body-parser:
router.post('/user/create', (req, res, next) => {
let body = [];
req.on('error', (err) => {
console.error(err);
}).on('data', (chunk) => {
// Data is present in chunks without body-parser
body.push(chunk);
}).on('end', () => {
// Finally concat complete body and will get your input
body = Buffer.concat(body).toString();
console.log(body);
// Set body in req so next function can use
// body-parser is also doing something similar
req.body = body;
next();
});
}, userController.addUser);
I have the following setup right now
test.js
var user = {
username: 'test_user',
email: 'test#test.me',
password: 'you shall not pass',
address: 'No where street'
};
chai.request(app)
.post('/api/v1/users')
.send(user);
I'm handling the post request in my routes/user.js
router.post('/', function(req, res, next) {
console.log('body: ' + req.body);
queries.insertUser(req.body)
.then(function(id) {
return queries.getSingleUser(id);
})
.then(function(user) {
res.status(200).json(user);
})
.catch(function(err) {
next(err);
});
});
req.body ends up being undefined. Any clue as to what might be going wrong?
The code is live at https://ide.c9.io/burtonium/node-from-scratch if anybody wants to have a look.
req.body being undefined is generally caused by either not using the body-parser middleware in Express, or declaring it incorrectly (for instance, after the route that wants to access req.body).
Assuming that Chai sends JSON, add this to your Express app:
app.use(require('body-parser').json());
(before you declare the routers)
{ [Error: Invalid login: 535 5.0.0 Authentication Failed] code:
'EAUTH', response: '535 5.0.0 Authentication Failed',
responseCode: 535 }
It keeps giving me this error, tried several times with different tutorials and still not working....
Also I know it will be hard to access to gmail's authentication and on top of that my gmail has two steps secure validation, so I decided to use Hotmail instead...
Here is code for my index.html
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script><script>
<script>
$(document).ready(function(){
var from,name,email,subject,text;
$("#submit").click(function(){
name=$("#name").val();
email=$("#email").val();
subject=$('#subject').val();`enter code here`
text=$("#message").val();
$("#messages").text("Sending E-mail...Please wait");
$.get("http://localhost:8000/send",{name:name,email:email,subject:subject,text:text},function(data){
if(data=="sent")
{
$("#messages").empty().html("
Email is been sent at "+to+" . Please check inbox !
");
}
});
});
});
</script>
below is my server.js code
var express = require('express');
var path = require('path');
var app = express();
var nodemailer = require("nodemailer");
app.use(express.static('assets'));
var smtpTransport = nodemailer.createTransport({
service: 'Hotmail',
auth: {
user: 'myemail.com',
pass: 'something'
}
});
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
app.get('/send', function(req, res){
var mailOptions={
from: "ME <my#hotmail.com>",
name : req.query.name,
To: req.query.email,
subject: req.query.subject,
text: req.query.message
};
console.log(mailOptions);
smtpTransport.sendMail(mailOptions, function(error, response){
if(error){
console.log(error);
res.end("error");
}else{
console.log("Message sent: " + response.message);
res.end("sent");
}
});
});
app.listen(8000, function(){`enter code here`
});
Hotmail might block connections from unexpected geographical locations, check your account security overview to see if you need to confirm any login attempts.
Additionally, if you use 2-factor auth for Hotmail then you need application specific password for Nodemailer, you can't use your account password in this case.
Using the default set up from the Nodemailer, the email will send with our internal mail server just fine when the app starts up with all code included on the app.js page.
//app.js
var nodemailer = require('nodemailer');
var transporter = nodemailer.createTransport({
host: 'mail.oursite.com',
});
var mailOptions = {
from: 'couponrequest#company.com', // sender address
to: 'myaddy#company.com', // list of receivers
subject: 'Hello ✔', // Subject line
text: 'Hello world ✔', // plaintext body
html: '<b>Hello world ✔</b>' // html body
};
// send mail with defined transport object
transporter.sendMail(mailOptions, function(error, info) {
if (error) {
return console.log(error);
}
console.log('Message sent: ' + info.response);
});
Then when switching things around it breaks and nothing happens when trying to make it happen from a button click.
App.js:
var nodemailer = require('nodemailer');
app.get('/users', routes.users);
Users.js
var express = require('express');
var router = express.Router();
var nodemailer = require('nodemailer');
/*
* POST to addcoupon Request.
*/
router.post('/addcoupon', function(req, res) {
// create reusable transporter object using SMTP transport
var transporter = nodemailer.createTransport({
host: 'mail.primeshine.com',
});
});
module.exports = router;
Index.js
var express = require('express');
var router = express.Router();
var nodemailer = require('nodemailer');
/*
* POST to addcoupon Request.
*/
router.post('/addcoupon', function(req, res) {
// create reusable transporter object using SMTP transport
var transporter = nodemailer.createTransport({
host: 'mail.primeshine.com',
});
});
module.exports = router;
Global.js
// Add Coupon Request
function addCoupon(event) {
event.preventDefault();
var mailOptions = {
from: 'couponrequest#company.com', // sender address
to: 'myaddy#company.com', // list of receivers
subject: 'Hello ✔', // Subject line
text: 'Hello world ✔', // plaintext body
html: '<b>Hello world ✔</b>' // html body
};
// send mail with defined transport object
transporter.sendMail(mailOptions, function(error, info) {
if (error) {
return console.log(error);
}
console.log('Message sent: ' + info.response);
});
};
I tried to use only the relevant code to send it. It works fine sending info to MongoDB for the button when it is adding user info but it doesn't submit anything when I try to have it send an email. Not sure if I have something in the wrong place or if something else is wrong... Thanks in advance for any help!
When I used nodemailer to send emails from my email account I had to create the transport with authentication:
/* define transportation */
var transport = nodemailer.createTransport(smtpTransport({
host: 'posteo.de',
port: 465,
secure: true,
auth: {
user: 'username',
pass: 'password'
},
maxConnections: 5,
maxMessages: 10
}));
Not sure if this if this is necessary for in your case but maybe it helps.