I'd like some feedback on the readability and style of the following code. It's a simple Node.js app that uses the Mailchimp API to add emails to a list. The client side handles SVGs, sign-up validation, and a contact modal with validation.
index.js (Node entry point)
const express = require('express');
const bodyParser = require('body-parser');
const request = require('superagent');
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static(__dirname + '/public'));
app.set('port', (process.env.PORT || 5000));
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.get('/', function (req, res) {
res.render('index');
});
app.listen(app.get('port'), function () {
console.log('Node app is running on port', app.get('port'));
});
var mailchimpInstance = process.env.MAILCHIMP_INSTANCE,
listUniqueId = process.env.MAILCHIMP_LIST_ID,
mailchimpApiKey = process.env.MAILCHIMP_API_KEY;
app.post('/signup', function (req, res) {
request
.post('https://' + mailchimpInstance + '.api.mailchimp.com/3.0/lists/' + listUniqueId + '/members/')
.set('Content-Type', 'application/json;charset=utf-8')
.set('Authorization', 'Basic ' + new Buffer('any:' + mailchimpApiKey).toString('base64'))
.send({
'email_address': req.body.email,
'status': 'subscribed'
})
.end(function (err, response) {
if (response.status < 300 || (response.status === 400 && response.body.title === 'Member Exists')) {
res.send(true);
} else {
res.send(false);
}
});
});
main.js (client side)
$(document).ready(function () {
emailjs.init("user_e00V3mHLZYEOvZAHpjKOt");
$('img[src$=".svg"]').each(function () {
var $img = jQuery(this);
var imgURL = $img.attr('src');
var attributes = $img.prop("attributes");
$.get(imgURL, function (data) {
// Get the SVG tag, ignore the rest
var $svg = jQuery(data).find('svg');
// Remove any invalid XML tags
$svg = $svg.removeAttr('xmlns:a');
// Loop through IMG attributes and apply on SVG
$.each(attributes, function () {
$svg.attr(this.name, this.value);
});
// Replace IMG with SVG
$img.replaceWith($svg);
}, 'xml');
});
});
$('#signup-form').on('submit', function () {
var data = {};
var emailInput = document.getElementById('email');
data.email = emailInput.value;
$.ajax({
type: 'POST',
data: JSON.stringify(data),
cache: false,
contentType: 'application/json',
datatype: 'json',
url: '/signup',
success: function (returns) {
if (returns) {
showSuccess('#email')
swal('Congratulations!', 'Please check your email to confirm your subscription.', 'success')
} else {
showError('#email')
swal({
title: 'Error!',
text: 'Please check your email address again.',
type: 'error'
});
}
}
});
return false;
});
$('.toggle-modal').on('click', function () {
$('#contact-modal').toggleClass('is-active');
});
$('#contact-button').on('click', function () {
var email = document.getElementById('email-input').value;
var name = document.getElementById('name-input').value;
var message = document.getElementById('message-input').value;
var valid = true
valid = isValid(name, '#name-input');
valid = isValid(email, '#email-input');
valid = isValid(message, '#message-input');
if (valid) {
$('#contact-button').toggleClass('is-loading');
emailjs.send(
"gmail",
"contact_me", {
"reply_to": email,
"from_name": name,
"message_html": message
}
).then(function (response) {
resetForm();
swal('Thanks!', 'You\'ll be hearing from us shortly.', 'success')
}, function (err) {
resetForm();
swal({
title: 'Error!',
text: 'Please try again later.',
type: 'error'
});
});
}
});
function resetForm() {
// Remove loading state and close the modal
$('#contact-button').toggleClass('is-loading');
$('#contact-modal').toggleClass('is-active');
var ids = ['#name-input', '#email-input', '#message-input']
for (var i = 0; i < ids.length; i++) {
input = ids[i]
$(input).val('');
$(input).removeClass('is-success');
$(input).removeClass('is-danger');
$(input + '-success').addClass('is-hidden');
$(input + '-warning').addClass('is-hidden');
}
}
function isValid(value, input) {
if (isEmpty(value) || isBlank(value)) {
showError(input)
return false
} else {
showSuccess(input)
return true;
}
}
function showError(input) {
$(input).removeClass('is-success');
$(input).addClass('is-danger');
$(input + '-success').addClass('is-hidden');
$(input + '-warning').removeClass('is-hidden');
$(input + '-button').addClass('is-danger');
}
function showSuccess(input) {
$(input).removeClass('is-danger');
$(input).addClass('is-success');
$(input + '-success').removeClass('is-hidden');
$(input + '-warning').addClass('is-hidden');
$(input + '-button').removeClass('is-danger');
$(input + '-button').addClass('is-primary');
}
function isEmpty(str) {
return (!str || 0 === str.length);
}
function isBlank(str) {
return (!str || /^\s*$/.test(str));
}
Full code available here - https://github.com/leerob/Drink