Use email template for contact form using Express/Sendgrid - javascript

I have a simple contact form using the Node Sendgrid helper library.
I would like to use a template email/contact.jade that compiles to HTML and adds the right context. I know it needs to go in the payload.html value, however I'm stuck on how to send the email with the template.
routes.js
app.route('/contact')
.post(function(req, res) {
var template = 'email/contact.jade';
var payload = {
to: req.body.email,
from: 'example#example.com',
subject: req.body.subject,
html: req.body.message
};
var email = new sendgridClient.Email(payload);
sendgridClient.send(email, function(err, json) {
if (err) {
return console.error(err);
} else {
res.redirect('/thanks');
}
});
});
email/contact.jade
p Thanks
p Name {{ name }}
p Email {{ email }}
p Subject {{ subject }}
p Message {{ message }}

First I'm not sure your jade syntax is correct. You could try this instead:
email/contact.jade
p Thanks
p Name #{name}
p Email #{email}
p Subject #{subject}
p Message #{message}
And to render this into HTML:
var jade = require('jade');
var templatePath = __dirname + '/contact.jade';
app.route('/contact')
.post(function(req, res) {
var payload = {
to: req.body.email,
from: 'example#example.com',
subject: req.body.subject,
html: jade.renderFile(templatePath, req.body)
};
//...
});

Related

How to fetch the text in a tag which contains translate in angular?

Here is my html,
<p id="on-board" class="on-board-text">
{{
'OVERVIEW.WELCOME_SCREEN_ON_BOARD'
| translate
: {
USER_NAME:
username
}
}}</p>
Where,
username = 'banner works!';
I am trying to fetch the value of USER_NAME.
Here is my spec,
it('Check if username is populated', async () => {
const { find } = await shallow.render({});
const htmlDiv = find('.on-board-text');
const user = htmlDiv.nativeElement.textContent.trim();
expect(user).toEqual('banner works!');
});
But here I am getting 'user' in spec as empty (" ").
Can anyone please suggest me help.Thanks.

Flask-Socket, key error when selecting rooms

Please forgive me if i posted it in bad way, but i dont have any idea where is the mistake.
Im doing a small chat with five rooms using Flask-Socket and SocketIO. I set rooms like this:
ROOMS = ["waiting room", "food", "news", "games", "coding"]
Then i put them to html:
#app.route("/chat", methods=['GET', 'POST'])
#login_required
def chat():
return render_template('chat.html', username=current_user.username, rooms=ROOMS)
And on template:
{%for room in rooms%}
<p class="select-room"> {{ room }}</p>
{% endfor %}
The problem is when i try to send message only to room where i am by:
#socketio.on('message')
def message(data):
time_stamp = time.strftime('%b-%d %I:%M%p', time.localtime())
send({'msg': data['msg'], 'username': data['username'], 'time_stamp':time_stamp}, room=data['room'])
and from client:
document.querySelector('#send-message').onclick = () =>{
socket.send({'msg': document.querySelector('#user_message').value,
'username': username, 'room': room});
}
It makes me key error:
send({'msg': data['msg'], 'username': data['username'], 'time_stamp':time_stamp}, room=data['room'])
KeyError: 'room'
it also happens when i trying to switch rooms(leave one and connect other using this):
function leaveRoom(room) {
socket.emit('leave', {'username': username, 'room': room});
document.querySelectorAll('.select-room').forEach(p => {
p.style.color = "black";
});
}
function joinRoom(room) {
socket.emit('join', {'username' : username, 'room' : room});
// Clear message area
document.querySelector('#display-message-section').innerHTML = '';
};
For room select i use:
document.querySelectorAll('.select-room').forEach(p => {
p.onclick = () => {
let newRoom = p.innerHTML
// Check if user already in the room
if (newRoom == room) {
msg = `You are already in ${room} room.`;
printSysMsg(msg);
} else {
leaveRoom(room);
joinRoom(newRoom);
room = newRoom;
};
};
});
Where im making a mistake?
The full code is here:
https://pastebin.com/QXiBQG2u
https://pastebin.com/zfEtV4ZX
https://pastebin.com/wfkqNjf9

express validator; error variable not defined within ejs

I have an issue that I've been trying to figure out for some time now, and was hoping someone may be able to point me in the right direction.
My variable (error) that I'm passing along in the res.render{} object, is unusable within my layouts file. The issue is logging as a reference error.
If I take the ejs code out, my error properly logs to the terminal; I'm just unable to use it within my layout file.
Following is the layout.ejs code, in part.
<% for(var i = 0; i < errors.length - 1; i++){ %>
<li> <%= errors[i] %> </li>
<% } %>
and POST...
//POST route
app.post('/articles/add', function(req, res){
req.assert('title', 'Enter title').notEmpty();
req.assert('author', 'Enter author').notEmpty();
req.assert('body', 'Enter an article').notEmpty();
//get errors
req.getValidationResult().then(function(err){
if(err.isEmpty()){
console.log(err);
res.render('add_article',{
title: 'Add Article',
errors: err // <-
});
}
else {
let article = new Article();
article.title = req.body.title;
article.author = req.body.author;
article.body = req.body.body;
article.save(function(e){
if(e) {console.log(e)}
else{
req.flash('success', 'Article Added');
res.redirect('/');
}
});
}
});
Thanks for any help.
As per I see there are two bugs within your code. First, the if(err.isEmpty()), when err is empty then you are trying to send err!! And another is use of req.getValidationResult(), it will resolve with result object not an array. Below is the code that might help.
//POST route
app.post('/articles/add', function(req, res){
req.assert('title', 'Enter title').notEmpty();
req.assert('author', 'Enter author').notEmpty();
req.assert('body', 'Enter an article').notEmpty();
//get errors
req.getValidationResult().then(function(result){
if(!err.isEmpty()){
console.log(err);
res.render('add_article',{
title: 'Add Article',
errors: result.array() // <-
});
}
else {
let article = new Article();
article.title = req.body.title;
article.author = req.body.author;
article.body = req.body.body;
article.save(function(e){
if(e) {console.log(e)}
else{
req.flash('success', 'Article Added');
res.redirect('/');
}
});
}
});
And the result.array() will produce something like this:
[
{param: "email", msg: "required", value: "<received input>"},
{param: "email", msg: "valid email required", value: "<received input>"},
{param: "password", msg: "6 to 20 characters required", value: "<received input>"}
]

Sometimes Handlebars does not load object

I'm trying to create divs using an object I pass with res.render(). However, sometimes the divs are created and sometimes they are not (if I refresh the page). I also use Bootstrap.
js/express:
router.get('/', checkSignIn, function(req, res, next) {
db = new sqlite3.Database(file);
var tasks = {};
db.serialize(function () {
var query = "SELECT tasks.id, tasks.name, tasks.status FROM tasks JOIN users ON users.privilege = tasks.privilege WHERE users.id = '" + req.session.userid + "'";
db.all(query, function (err, rows) {
for(i = 0; i < rows.length; i++) {
tasks[i] = {
name: rows[i].name,
status: rows[i].status
};
console.log(tasks[i]);
}
});
});
db.close();
res.render('index', {
title: 'Home',
css: ['style.css', 'dist/wu-icons-style.css'],
username: req.session.username,
tasks: tasks
});
});
hbs:
<div class="container">
<div class="row">
<div class="col-md-6">
<div class="panel-group">
{{#each tasks}}
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">{{name}}</h3></div>
<div class="panel-body">{{status}}</div>
</div>
{{/each}}
</div>
</div>
</div>
</div>
The tasks object is properly populated every time, according to the console.log() that I've added. So I think the problem lies in Handlebars.
I kind of found a solution here: Handlebars not print {{this}} in each helper, but I don't use this. I tried ./name and ./status, but it didn't help. Can someone help me out here?
Your issue is async javascript, not handlebars. Your tasks object is populating, but you're rendering the html prior to that. If you console.log(tasks) right after the current position of db.close(), it will be an empty object. You need to move the render function inside the database call:
router.get('/', checkSignIn, function(req, res, next) {
db = new sqlite3.Database(file);
db.serialize(function () {
var query = "SELECT tasks.id, tasks.name, tasks.status FROM tasks JOIN users ON users.privilege = tasks.privilege WHERE users.id = '" + req.session.userid + "'";
db.all(query, function (err, rows) {
var tasks = {};
for(i = 0; i < rows.length; i++) {
tasks[i] = {
name: rows[i].name,
status: rows[i].status
};
console.log(tasks[i]);
}
res.render('index', {
title: 'Home',
css: ['style.css', 'dist/wu-icons-style.css'],
username: req.session.username,
tasks: tasks
});
});
});
db.close();
});

AngularJs binding model attribute to checkbox

I am trying to assign some tags on post creation.
I have a Post model that looks like this:
var mongoose = require('mongoose');
var PostsSchema = {
title: String,
content: String,
postedBy: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Users'
},
comments: [{
text: String,
postedBy: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Users'
},
}],
tags: [String]
};
I am trying to bind the some checkboxes to the 'tags' array attribute in the Post.
This how my post router looks like:
///* Create post */
postRouter.route('/').post(function (req, res) {
mongoose.createConnection('localhost', 'CMS');
console.log(req.body);
var post = {
title: req.body.title,
content: req.body.content,
tags: req.body.tags
};
if (typeof req.body.title === "undefined" || typeof req.body.content === "undefined")
{
res.json({message:"Error"});
}else
{
var newPost = new Posts(post);
newPost.save(function (err, post) {
if (err) res.json({message:"Error"});
res.json(post);
});
}
});
My controller looks like:
$scope.createPost = function(post){
postService.createPost(post);
postService.getPosts()
.then(modelPosts);
}
And my view look like:
div(ng-controller='postController')
h2 Create Post
form
div.form-group
label(for='title') Title
input(type='text', class='form-control', id='title', name='title', placeholder='Title', ng-model='newpost.title', autofocus)
div.form-group
label(for='password') Content
input(type='text', class='form-control', id='content', name='content', placeholder='content', ng-model='newpost.content')
div(ng-controller='tagController')
h2 Tags
div( ng-model='Tags', ng-init='getTags()')
ul( ng-repeat='tag in Tags')
li
label
input(ng-model='newpost.tag',value='{{tag.name}}', type='checkbox', name='tag[]')
span {{tag.name}}
button( ng-click='createPost(newpost)', class='btn btn-small btn-primary') Create Post
I am not sure what is the problem with the binding my view to the model. Tags are rendered and checkboxes are created , but when i check one checkbox , all of them get checked.
input(ng-model='newpost.tag', ng-value-true='tag.name', ng-value-false='null' type='checkbox', name='tag[]')
Docs Input[checkbox]

Categories

Resources