node-mandrill sending mail via server - javascript

this is a newbie question on using node-mandrill properly and most probably on node itself as I am still trying to learn it. But since I have seen many examples to use the api key of mandrill directly from the client side and therefore revealing it, I was wondering how exactly it was working when served but got stuck at this point:
I have an app.js serving a public folder...
app.js
var express = require('express');
var mandrill = require('node-mandrill')(API_KEY);
var app = express();
app.use(express.static('public'));
app.listen(PORT);
function sendEmail ( _name, _email, _subject, _message) {
mandrill('/messages/send', {
message: {
to: 'EMAIL',
from: [{email: _email , name: _name}],
subject: _subject,
text: _message
}
}, function(error, response){
if (error) console.log( error );
else console.log(response);
});
}
...where a client script is used to collect info from a contact form and send an email upon clicking a submit button.
form.js
var contactForm = document.getElementById( 'contactForm' );
new stepsForm( contactForm, {
onSubmit : function( form ) {
// send email
var _subject = 'Contact Request';
var _email = contactForm.elements['q4'].value;
var _name = contactForm.elements['q5'].value;
var _message = contactForm.elements['q6'].value;
sendEmail(_name,_email,_subject,_message);
}
} );
Could you please tell me what's missing/wrong?
Thanks.

You can't call your back-end function from client. You can use Jquery to make Ajax call like:
$(document).ready(function(){
$('#contactForm').submit(function(event) {
event.preventDefault();
var _subject = 'Contact Request';
var _email = contactForm.elements['q4'].value;
var _name = contactForm.elements['q5'].value;
var _message = contactForm.elements['q6'].value;
$.ajax({
url: '/sendEmail',
method: 'post',
contentType: 'application/json',
data: JSON.stringify({ subject: _subject, email: _email}),
success: function(res) {
}
})
})
})
And in your back-end:
// some lines skipped
app.post('/sendEmail', function(req, res) {
//do your stuff
})

Related

When using a fetch request in a Node JS server it receives the body as blank

I was working on a user login system in Node JS and was making a POST request to the server like this.
let data = {
username: "John Doe",
password: "123abc",
}
let options = {
method: 'POST',
headers: {
"Content-type": "application/json"
},
body: JSON.stringify(data),
}
fetch('/verify-login', options).then(function(r) {
return r.text();
}).then(function(dat) {
if (dat == 'n') {
document.getElementById('login-fail').innerHTML = 'User name or password is incorrect!';
} else {
console.log('Login Success');
}
});
Server Side code:
const express = require('express');
const port = 80;
const bodyParser = require("body-parser");
const fs = require('fs');
var app = express();
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
const cors = require("cors");
app.use(cors());
app.post('/verify-login', async function(q, r) {
let dat = await q.body; //<-- Body is just {} not what the fetch request sent
//do account check stuff with dat
if (success) {
r.send('y');
} else {
r.send('n');
}
});
app.listen(port, function() {
console.log("Started application on port %d", port);
});
This issue is that on the server side when I receive the request, the body is returned with '{}'. Does anybody know why this is happening and how I can fix it?
There are various data types you can pass to fetch through the body option.
If you pass something it doesn't recognise, it converts it to a string and sends that.
Converting a plain object to a string doesn't give you anything useful.
let data = {
username: "John Doe",
password: "123abc",
}
console.log(`${data}`);
You said you were sending JSON (with the Content-Type header. So you need to actually send JSON.
const json = JSON.stringify(data);

The Resource submitted could not be validated: Mailchimp Status 400

I have been trying to make a Simple Newsletter signup Form where I am Taking basic details from the User and sending that data to Mailchimp using API's.
I am facing the problem in sending POST HTTPS Request. Tried reading different answers but not able to solve problems.
Here's the screenshot of the Issue.
Code :
app.post("/", function (req, res) {
const firstName = req.body.fname;
const lastName = req.body.lname;
const email = req.body.email;
const data = {
members: [
{
email_address : email,
status: "subscribed",
merge_fields: {
FIRSTNAME: firstName,
LASTNAME: lastName
}
}
]
};
var jsonDATA = JSON.stringify(data);
const url = "https://us1.api.mailchimp.com/3.0/lists/<My_LIST_ID>/members/"; //Removed List Id for now to post Question.
const options = {
method: "POST",
auth: "pranshukas:MY_API_KEY" //Removed API_KEY to post the Question
}
const request = https.request(url, options, function (response) {
response.on("data", function (data) {
console.log(JSON.parse(data));
})
});
request.write(jsonDATA);
request.end();
});
I also tried using POSTMAN and there I am able to successfully send the Request to the Server and add details. But facing a Problem when I am implementing on my local server.
Please Help me out I know I am making some mistake in making post HTTPS request but stuck where.
Looks like you have some problem with the email address input, The email address field is blank and it should be populated with the email address.
Also, I think you can delete the group name(members) from the URL
const url = "https://us1.api.mailchimp.com/3.0/lists/<My_LIST_ID>/";
As recommendation i think you should add a failure route, in case of failure.
just for example:
You can make two different routes/pages for success and failure.
you can add this inside the const request anonymous function after having this routes.
if(response.statusCode === 200) {
res.sendFile(__dirname + "/success.html");
} else {
res.sendFile(__dirname + "/failure.html");
}

Unexpected token - while parsing json request

I have two node servers and I am trying to send files between them using a rest api. However when I am sending the data I get a "Unexpected token -"on the receiving server. On the sender I get an [Error: write after end].
My router code:
var express = require('express');
var multer = require('multer');
var path = require('path');
var Router = express.Router;
const MODULES_PACKAGES_UPLOAD_DIR = path.resolve('/tmp');
module.exports = function() {
var router = new Router();
var storage = multer.diskStorage({
destination: function(req, file, cb){
cb(null, MODULES_PACKAGES_UPLOAD_DIR);
}
});
var upload = multer({storage: storage});
router.post('/fileUpload', upload.array(), function(req, res){
debug('We have a a file');
//Send the ok response
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain; charset=utf-8');
res.end('\n');
}
The sending code:
var Util = require('util');
var http = require('request-promise');
var request = require('request');
var fs = require('fs');
var Post = require('http');
var FormData = require('form-data');
//Generate the form data
var formdata = modules.map(function(fileName){
return fs.createReadStream('/opt/files/'+fileName);
});
var data = getData(); //Gets the body of the code as a promise
return Promise.all(data)
.then(function(dataResults){
var options = {
method: 'POST',
uri: 'https://' + name +'/file',
rejectUnauthorized: false,
timeout: 2000,
body: {
keys: keyResults,
modules: modules,
},
formData: { <====== If I remove this section everything works
'module-package': formdata,
},
json: true // Automatically stringifies the body to JSON
};
request.post(options, function(err, response){
if( err){
debug('Error: ',err);
}
else{
debug('We posted');
}
});
The weird thing is that if I remove the formData section then everything works but when it is there I get an exception that says:
SyntaxError: Unexpected token -
at parse (/home/.../projects/node_modules/body-parser/lib/types/json.js:83:15)
Does anyone have any idea what I could be doing wrong??
Just in case anyone in the future comes with the same problem. As #Bergi mentioned. You cant have both json data and form data. You need to choose either one. The solution is to just pass the json data as apart of the form like.
var options = {
method: 'POST',
uri: 'https://' + name +'/file',
rejectUnauthorized: false,
timeout: 2000,
body: {
},
formData: {
'module-package': formdata,
keys: keyResults,
modules: modules,
},
json: true // Automatically stringifies the body to JSON
};
request.post(options, function(err, response){
if( err){
debug('Error: ',err);
}
else{
debug('We posted');
}
});
In my case, the header of the HTTP Request contained "Content-Type" as "application/json".
So here are the things to check:
Send only either form-data or json body. NOT BOTH.
Check for Headers if the "Content-Type" is mentioned. Remove that.

How do I transfer data from a client-side form input to a server-side Nodejs script?

I'm trying to implement functionality which takes data from form inputs on the client-side and sends it to the server to be processed by my Nodejs backend.
I've got the server-side function working, but I'm unsure as to how I would go about sending the data from the client-side form to my backend server via the $.ajax GET request that submits the form.
The code I have so far:
Server side function:
app.get('/id', function(req,res) {
var query = "SELECT * FROM Control";
connection.query(query, function() {
console.log(query);
});
});
Client side function:
function select()
{
$.ajax({
type: 'get',
url: '/id',
success: function(data) {
var ceva = data;
console.log('#ceva');
},
error: function(err) {
console.log(err);
}
});
}
You want to use a POST request rather than a GET request. Doing so will allow you to send data along with the request that you can then use in your query on the server side and send the response back to your client. Like so:
Client Side
function select() {
var id = $('#My-ID-Input').val();
$.ajax({
type: 'post',
url: '/id',
data : {
id : id
},
success: function(data) {
var id = data.id;
$('#My-ID-Input').val(id);
},
error: function(err) {
console.log(err);
}
});
}
Server Side
app.post('/id', function(req, res) {
var data = req.body;
var id = data.id;
var query = "SELECT * FROM Control WHERE id=" + id;
connection.query(query, function(error, result) {
console.log(result);
res.send(result);
});
});
GOTCHA!
You need to make sure that you have the express bodyparser
middleware implemented into your server to ensure that the data sent
as the body of the post request is then parsed into an object literal
on the server side. In your server module/file, you'll need to include the following code, and ensure that you've npm install body-parser:
var bodyParser = require('body-parser');
app.use( bodyParser.json() );

nodejs hapiJs: Sending, receiving data from client

I have the following files; client.js and server.js. I want to send data to my server, using ajax. I manage to send the searched username, but the domain is received on the server as undefined. I am not sure if I am missing something on the client side, or the server side, or both?
On the server side, my function should be a generic function to allow it to receive any domain and the issue the request on that domain.
Can anyone help out please?
Cliente:
$(document).ready(function(){
console.log("Ready!");
var domains=[ ]; //pass domain names into array for easier iteration
domains.push($(".facebook").find("a").text());
domains.push($(".github").find("a").text());
domains.push($(".twitter").find("a").text());
domains.push($(".instagram").find("a").text());
domains.push($(".pinterest").find("a").text());
console.log(domains);
$("#searchbutton").on('click', function(event){
var username = $("#searchname").val().trim(); // store value from searchbox
console.log(username);
if(username === ""){
event.preventDefault();
}
if(username){
var newhtml = "<p>";
newhtml += username;
newhtml += "</p>";
$(".username").html(newhtml);
$(".username").remove("newhtml");
var domainCheck = function(domainName){
$.ajax({
url: "/"+username,
type: "get",
data: {domainName: domainName, username: username},
success: function(response){
console.log(domainName);
console.log(response);
}
});
};
//send ajax request to server for each domain name to check for username availability
var len = domains.length;
for(var i = 0; i<len; i++){
domainCheck(domains[i]);
console.log(domains[i]+'\n');
}
}
});
});
Server:
var Hapi = require('hapi');
var request = require('request');
var server = Hapi.createServer('localhost', 8080);
var routes =[
{
path: "/",
method: "GET",
handler: function (req, reply){
console.log("Home page loaded and runnning!");
reply.file('index.html');
}
},
{
path: '/{username}',
method: 'GET',
handler: function (req, reply){
// this is not working. the domain name is not being received from the client side. instead its passing undefined!
request('http://www.'+ req.domain.domainName +'.com/' + req.params.username, function(error, response, body){
console.log("Request received");
console.log(response.statusCode);
if ( response.statusCode === 404 ) {
console.log( "Username " + req.params.username + " is available on " + req.domain.domains);
reply({"available":"yes"});
}
if ( response.statusCode === 200 ) {
console.log( "Username " + req.params.username + " is already taken on " + req.domain.domains);
reply({"available":"no"});
}
});
}
},
{
method: 'GET',
path: '/static/{param*}',
handler: {
directory: {
path: 'static'
}
}
}
];
server.route(routes);
server.start(function() {
console.log("Server started", server.info.uri);
});
module.exports = server;
Change req.domain.domainName to req.query.domainName. When you access request data, you need to specify whether it is in the query, in the payload, etc.

Categories