how to display data after form submit using expressjs - node.js

**app.js** Code
app.get('/', function (req, res) {
res.render('index', {
data: docsData,
title: "EJS example",
header: "Some users"
});
});
app.post('/', function (req, res) {
var jname= req.body.firstname;
var lname= req.body.lastname;
var jemail= req.body.email;
var collection = dbConnect.collection('users');
var document={name:jname, lastname:lname, email:jemail};
collection.insert(document, {w: 1}, function(err, records){
console.log("Record added as "+records[0]._id);
});
dbConnect.collection("users").find({"name":jname}).toArray(function(err, docsData) {
console.log('checking error',err, docsData);
res.render('index', {
data: docsData,
title: "AJT Family",
header: "Some users"
});
});
});
**html code**
<div align="center" ng-controller="FormCtrl">
<form name="form" ng-submit="submitForm()" novalidate>
<table>
<tr><td>Name:</td>
<td>
<input id="firstname" type="text" ng-model="regform.firstname" name="firstname" required="" />
</td>
<td>
<div ng-show="form.$submitted || form.firstname.$touched">
<div ng-show="form.firstname.$error.required">Enter your name.</div>
</div>
</td>
</tr>
<tr>
<td>Last Name: </td>
<td>
<input id="lastname" name="lastname" type="text" ng-model="regform.lastname" required>
</td>
<td>
<div ng-show="form.$submitted || form.lastname.$touched">
<div ng-show="form.lastname.$error.required">Enter your Last name.</div>
</div>
</td>
</tr>
<tr>
<td>E-mail:</td>
<td><input id="email" type="email" ng-model="regform.email" name="uEmail" required="" /></td>
<td>
<div ng-show="form.$submitted || form.uEmail.$touched">
<span ng-show="form.uEmail.$error.required">Enter your email.</span>
<span ng-show="form.uEmail.$error.email">This is not a valid email.</span>
</div>
</td>
</tr>
</table>
<input type="button" ng-click="reset(form)" value="Reset" />
<input type="submit" ng-disabled="!form.$valid" value="Save" />
<p id="hu"></p>
</form>
</div>
<%if(data) {%>
<h1>Users</h1>
<% data.forEach(function(user){ %>
<br>
<table>
<tr><td>Name: </td><td><%= user.name %> <%= user.lastname %></td></tr>
<tr><td>Email: </td><td><%= user.email %></td></tr>
</table>
<% }) %>
<% } %>
</body>
</html>
**javascript**
var result;
var app = angular.module('formExample', []);
app.controller('FormCtrl', function ($scope, $http) {
$scope.data = {};
$scope.submitForm = function() {
formData = $scope.regform;
console.log("posting data....");
var request = $http({ url: '/',data: $scope.regform, method: 'post' });
console.log(formData);
};
});
here I can save data on mongodb using expressjs. I need to display data after form submission. Here nothing is displaying after form submission. How to display that saved content in html using embedded Javascript.

What you'll want to do is change your res.render() call to do something like this:
res.render('index', {
data: docsData,
title: 'AJT Family',
header: 'Some Users',
body: req.body, // This is your form data as a JSON object.
});
Then, in your index template, you'll have access to your form data to display however you want, if you're using Jade, for instance, you might want to say like:
h1 Data!
p #{body}

Related

Login form, Angular 5 and nodeJS

I'm trying to implement a form using Angular5 and NodeJS
The original form, I was given, is set up as:
<form action="https://www.myUrl.co.uk/signin" method="post">
<table border="0">
<tbody>
<tr>
<td>Username:</td>
<td><input id="Username" name="email" type="text" /></td>
</tr>
<tr>
<td>Password:</td>
<td><input id="Password" name="password" type="password" /></td>
</tr>
<tr>
<td></td>
<td><input name="submit" type="submit" value="Login" /></td>
</tr>
</tbody>
</table>
</form>
I've noticed that in the headers the form Data sends:
email=some#email.co.uk&password=omsmmsms&submit=Login
In order to use it within Angular I've set app as follows
template form:
<form name="clientForm" id="clientForm" novalidate [formGroup]='clientForm' (ngSubmit)="submitForm()">
<div class="row control-group">
<label for="userName">UserName</label>
<input formControlName="userName" type="text" class="form-control" placeholder="UserName" id="userName">
<label for="password">Password</label>
<input formControlName="password" type="password" class="form-control" placeholder="password" id="password">
<div class="row">
<div class="form-group col-xs-12">
<button type="submit" class="btn btn-lg" >Send</button>
</div>
</div>
</div>
</form>
The component file:
submitForm() {
const userName = this.clientForm.get('userName').value;
const password = this.clientForm.get('password').value;
this.contactService.client(userName, password)
.subscribe((response) => {
if (response.msg === 'sent') {
this.success = response.sucess;
this.clientForm.reset();
}
});
}
This subscribes to a observable function in a service:
public client(userName, password): Observable<any> {
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/X-www-form-urlencoded',
})
};
let body = "Username="+userName+"&password="+password;
return this.http.post(this.url+'contact/client', body, httpOptions)
.map((response) => {
//window.open('https://www.accountancymanager.co.uk/myinfo', '_blank');
return response;
})
.catch((error: Response) => Observable.throw(error.json()) )
}
The service connect to a NodeJS route below:
router.post('/client', function (req, res) {
var options = {
url: 'https://www.accountancymanager.co.uk/signin',
method: 'POST', // Don't forget this line
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'X-MicrosoftAjax': 'Delta=true',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:24.0) Gecko/20100101 Firefox/24.0',
},
form: {
'Username' :req.body.Username,
'Password' :req.body.password
}
};
request(options, (err, response, body) => {
if (err) {
console.log(err);
} else {
res.json('something')
console.log(options.form);
}
});
});
I get no errors from the above, but how do I send the user in the Angular app to the login page after success?
Simply redirecting doesn't work.
Or is there another way?
Maybe sending all data from the service, no NodeJS?
Let me know if unclear
put this in your code:
import {Router} from '#angular/router';
constructor(private router: Router) {
}
submitForm() {
const userName = this.clientForm.get('userName').value;
const password = this.clientForm.get('password').value;
this.contactService.client(userName, password)
.subscribe((response) => {
if (response.msg === 'sent') {
this.success = response.sucess;
// this.clientForm.reset();
this.router.navigate(['your route']);
}
});
}

JSON value returning as 'undefined' despite being well formed in nodeJS and SQLite3

I am trying to do multiple async requests to a SQLite database and then render them in a web page using node/express and ejs templating. I am able to retrieve the data in JSON from the database request but when pushing it to another JSON object, it is returning as undefined.
app.js
//Set up web server
const express = require('express');
const app = express();
var dashboard = require('./dashboard.js');
var async = require('async');
//Set view engine and allow access to public/css
app.set('view engine', 'ejs');
app.use(express.static('public/css'));
//Start server
app.listen(3000, function () {
console.log('Example app listening on port 3000!');
})
//Connect to database
const sqlite3 = require('sqlite3').verbose();
const db = new sqlite3.Database('fishtank.db');
//Home page
app.get('/', function(req, res) {
//Temps variables
var currentAmbientTemp = '18.2';
var lightStatus = 'OFF';
var airPumpStatus = 'OFF';
//Get temps from database
var tempHistoryQuery = "SELECT * FROM watertemp LIMIT 5";
var currentWaterTempQuery = "SELECT temp FROM watertemp LIMIT 1";
async.series({
tempHistory: function(callback){
db.all(tempHistoryQuery, (err, results)=> {
callback(results);
})
},
currentWaterTemp: function(callback){
db.all(currentWaterTempQuery, (err, results)=> {
callback(results);
})
}
},function(err, results) {
res.render('index', {
tempHistory: results['tempHistory'],
currentWaterTemp: results['currentWaterTemp'],
currentAmbientTemp: currentAmbientTemp,
lightStatus: lightStatus,
airPumpStatus: airPumpStatus
})
console.log(results);
});
});
index.ejs
<!-- views/pages/index.ejs -->
<!DOCTYPE html>
<html lang="en">
<head><% include partials/head %></head>
<body class="container">
<!--HEADER-->
<header><% include partials/header %></header>
<!--MAIN BODY-->
<main>
<!--OVERVIEW SECTION-->
<div class="row">
<div class="col-md-12 dash-section">
<h3>Overview</h3>
</div>
<!--WATER TEMP-->
<div class="col-md-3 dash-panel">
<div class="panel panel-info">
<div class="panel-heading">WATER TEMP</div>
<div class="panel-body"><%= currentWaterTemp %>°C</div>
</div>
</div>
<!--AMBIENT TEMP-->
<div class="col-md-3 dash-panel">
<div class="panel panel-info">
<div class="panel-heading">AMBIENT TEMP</div>
<div class="panel-body"><%= currentAmbientTemp %>°C</div>
</div>
</div>
<!--LIGHT STATUS-->
<div class="col-md-3 dash-panel">
<div class="panel panel-info">
<div class="panel-heading">LIGHT STATUS</div>
<div class="panel-body"><%= lightStatus %></div>
</div>
</div>
<!--AIR PUMP STATUS-->
<div class="col-md-3 dash-panel">
<div class="panel panel-info">
<div class="panel-heading">AIR PUMP STATUS</div>
<div class="panel-body"><%= airPumpStatus %></div>
</div>
</div>
</div>
<!--DETAILS SECTION-->
<div class="row">
<div class="col-md-12 dash-section">
<h3>Details</h3>
</div>
<!--WATER TEMP DETAILS-->
<div class="col-md-4">
<div class="panel panel-default">
<div class="panel-heading"><strong>WATER TEMP HISTORY</strong></div>
<table class="table table-bordered">
<thead>
<tr>
<th scope="col">Date/Time</th>
<th scope="col">Temp</th>
</tr>
</thead>
<tbody>
<% for(var i=0; i < tempHistory.length; i++) { %>
<tr>
<td><%= tempHistory[i].datetime %></td>
<td><%= tempHistory[i].temp %></td>
</tr>
<% } %>
</tbody>
</table>
</div>
</div>
<!--AMBIENT TEMP DETAILS-->
<div class="col-md-4 ml-auto">
Ambient Temp Table
</div>
<!--TBC DETAILS-->
<div class="col-md-4 ml-auto">
TBC
</div>
</div> <!--End of row-->
</main>
<!--FOOTER-->
<footer><% include partials/footer %></footer>
</body>
</html>
console.log(results); is giving me:
{ tempHistory: undefined }
But when logging it from within the callback function, I get:
[ { id: 1, datetime: '2018-02-24 12:56:02.123456', temp: 29.5 },
{ id: 2, datetime: '2018-02-24 13:56:02.123456', temp: 28.5 },
{ id: 3, datetime: '2018-02-24 14:56:02.123456', temp: 26.5 },
{ id: 4, datetime: '2018-02-24 15:56:02.123456', temp: 26.7 },
{ id: 5, datetime: '2018-02-24 16:56:02.123456', temp: 25.9 } ]
Any help would be greatly appreciated.
EDIT
I suspect now that you are calling back in the wrong way. The first parameter of callback should be an error and the result should be the second parameter. See below:
async.series({
tempHistory: function (callback) {
db.all(tempHistoryQuery, (err, results)=> {
callback(err, results);
})
},
currentWaterTemp: function (callback) {
db.all(currentWaterTempQuery, (err, results) => {
callback(err, results);
})
}
},function (err, results) {
// Don't forget to check for error here.
});
Which can be simplified to:
async.series({
tempHistory: cb => db.all(tempHistoryQuery, cb),
currentWaterTemp: cb => db.all(currentWaterTempQuery, cb)
}, (err, results) => {
// ..
});
For reference see the example code of .series

Data is not displaying nodejs handlebars

I am trying to display data from my database but it doesnt seem to show up, what I did is followed a tutorial for this on ejs and it seemed to work fine and I am now trying it on handlebars
app.get('/', function(req, res, next) {
req.db.collection('users').find().sort({"_id": -1}).toArray(function(err, result) {
if (err) {
req.flash('error', err);
res.render('user/list', {
title: 'Users List',
data: ''
});
} else {
res.render('user/list', {
title: 'Users List',
data: result
});
}
});
});
<table class="table table-striped">
<tr>
<th>Name</th>
<th>Type</th>
<th>Desciption</th>
<th>Action</th>
</tr>
{{#if user}}{{#each user}}
<tr>
<td>{{this.Name}}</td>
<td>{{this.Type}}</td>
<td>{{this.Description}}</td>
<td>
<div style="float:left">
<a href='/users/edit/{{ user._id}}'>Edit</a>
<form method="post" action="/users/delete/{{user._id}}" style="float:right">
<input type="submit" name="delete" value='Delete' onClick="return confirm('Are you sure you want to delete?')" />
<input type="hidden" name="_method" value="DELETE" />
</form>
</div>
</td>
</tr>
{{/each}}{{/if}}
</table>
This is the ejs project that I made by following a tutorial and it currently is working
<table width='80%' border=0>
<tr style='text-align:left; background-color:#CCC'>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Action</th>
</tr>
<!--
Using FOREACH LOOP for the users array
myArray.forEach(function(el, index) {
// el - current element, i - index
});
-->
<% if (data) { %>
<% data.forEach(function(user){ %>
<tr>
<td><%= user.Name %></td>
<td><%= user.Type %></td>
<td><%= user.Description %></td>
<td>
<div style="float:left">
<a href='/users/edit/<%= user._id %>'>Edit</a>
<form method="post" action="/users/delete/<%= user._id %>" style="float:right">
<input type="submit" name="delete" value='Delete' onClick="return confirm('Are you sure you want to delete?')" />
<input type="hidden" name="_method" value="DELETE" />
</form>
</div>
</td>
</tr>
<% }) %>
<% } %>
</table>
app.get('/', function(req, res, next) {
// fetch and sort users collection by id in descending order
req.db.collection('benefits').find().sort({"_id": -1}).toArray(function(err, result) {
if (err) {
req.flash('error', err);
res.render('user/list', {
title: 'User List',
data: ''
});
} else {
res.render('user/list', {
title: 'User List',
data: result
});
}
});
});
I just tried to convert the ejs code to handle bars with some reasearch on how it works but it did not turn out my way
I am still a beginner in using nodejs so please go easy on me
Not only you have to convert your templates from ejs to handlebars, but you also have to use handlebars middleware with express.
Here you will find one : https://www.npmjs.com/package/express-handlebars
Install it with, for example npm : npm install --save express-handlebars
Then, declare it in your server file :
var exphbs = require('express-handlebars');
var app = express();
Edit:
I see that you use a kind of 'partials' to render your users' list page, so you have to declare its path :
var hbs = exbphbs.create({
defaultLayout: 'main',
partialsDir: 'views/partials/',
});
app.engine('handlebars', hbs.engine);
app.set('view engine', 'handlebars');
Now your workspace should look like this :
app.js
views/
list.handlebars
layouts/
main.handlebars
partials/
user/
list.handlebars
In your template, you check the presence of a user var, so you have to name it in the render function, instead of data:. Plus, render the file list.handlebars
app.get('/', function(req, res, next) {
req.db.collection('users').find().sort({"_id": -1}).toArray(function(err, result) {
if (err) {
req.flash('error', err);
res.render('list', {
title: 'Users List',
user: '',
});
} else {
res.render('list', {
title: 'Users List',
user: result,
});
}
});
});
views/list.handlebars :
{{> user/list}}
views/layouts/main.handlebars
<!DOCTYPE html>
<html>
<head>
</head>
<body>
{{body}}
</body>
</html>
views/partials/user/list.handlebars : notice i removed this. and user.
<h1>{{title}}</h1>
<table class="table table-striped">
<tr>
<th>Name</th>
<th>Type</th>
<th>Desciption</th>
<th>Action</th>
</tr>
{{#if user}}
{{#each user}}
<tr>
<td>{{Name}}</td>
<td>{{Type}}</td>
<td>{{Description}}</td>
<td>
<div style="float:left">
<a href='/users/edit/{{ _id}}'>Edit</a>
<form method="post" action="/users/delete/{{_id}}" style="float:right">
<input type="submit" name="delete" value='Delete' onClick="return confirm('Are you sure you want to delete?')" />
<input type="hidden" name="_method" value="DELETE" />
</form>
</div>
</td>
</tr>
{{/each}}
{{/if}}
</table>

Image upload with multer cause other retrieved data to not display on the page

The new data doesn't show up on the page after I implement a feature where user can upload their images. I think it has to do something with enctype ="multipart-form-data" . If i don't include enctype in the form tag, the image upload feature doesn't work. How do i fix the problem?
app.js
app.get("/dashboard", function(req, res){
//get all posts from database
Post.find({}, function(err, posts){
if(err){
console.log(err);
}else{
res.render("index", {post:posts});
}
})
})
app.post("/dashboard", function(req, res){
//UPLOAD IMAGE
upload(req, res, (err) => {
console.log(req.file)
});
//CREATE NEW POST
Post.create(req.body.post, function(err, newPost){
if(err){
console.log(err);
}else{
console.log(req.body.post)
res.redirect("/dashboard")
}
})
})
index.ejs
<form action="/dashboard" method="POST" enctype="multipart/form-data">
<input type="text" class="form-control" name="post[title]">
<select class="form-control" name="post[category]">
<!--categories for posts -->
</select>
<!--ALLOW USER TO UPLOAD IMAGE-->
<input type="file" class="form-control-file" name="image">
<!--ALLOW USER TO WRITE CONTENT OF POST-->
<textarea class="form-control" name="post[content]"></textarea>
<button data-dismiss="modal">Close</button>
<input type="submit" >
</form>
index.ejs
<tbody>
<!--LOOPING OVER POSTS-->
<% post.forEach(function(post){ %>
<tr>
<td scope="row"><%= post.id %></td>
<td><%= post.title %></td>
<td><%= post.category %></td>
<td><%= post.date %></td>
<!--BUTTON TO GO TO SHOW PAGE-->
<td><a href="/show" class="btn btn-secondary">
<i class="fa fa-angle-double-right"> Details</i>
</a></td>
</tr>
<% }) %>
</tbody>

Set input field value with data from mongoose

Hi,
I'm trying to get value from mongoose and populate textbox with it. So basically when I click Edit button I would like the name of the department appear in Department name textbox. I tried multiple things but failed. ($('#departmentName').val(department.name) for example) How can I do it properly? Thank you.
my department handlebar
<h2>Departments List</h2>
<div class="row">
<div class="col-lg-12">
<table class="table">
<thead>
<tr>
<th>Name</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr>
<form method="POST" action="/departments/create_department">
<td><input class="form-control" type="text" placeholder="Department Name" name="departmentName" id="departmentName"></td>
<td><button class="btn btn-primary" type="sumit">Add Department</button></td>
</form>
<td><button class="btn btn-info">Update</button></td>
<td><button class="btn btn-info">Clear</button></td>
</tr>
{{#each departments}}
<tr>
<form method="POST" action="/departments/remove_department/{{_id}}?_method=DELETE">
<td>{{name}}</td>
<td><button class="btn btn-danger" type="submit">Remove</button></td>
</form>
<form method="GET" action="/departments/edit_department/{{_id}}?">
<td><button class="btn btn-warning" value={{id}} type="submit">Edit</button></td>
</form>
</tr>
{{/each}}
</tbody>
</table>
</div>
</div>
my department controller
var express = require('express');
var router = express.Router();
var passport = require('passport');
var mongoose = require('mongoose');
var Departments = require('../models/department');
var User = require('../models/user');
// List of departments
router.get('/add_department', userAuthenticated, function(req, res, next) {
Departments.find(function(err, departments) {
if (err) {
throw err;
}
res.render('add_department', {title:'Add New Department', departments: departments, name: departments.name, id: departments._id})
})
});
// Edit department
router.get('/edit_department/:id', userAuthenticated, function(req, res, next) {
var departmentName = "";
Departments.findById(req.params.id).exec(function(err, department) {
if (err) {
throw err;
} else {
$('#departmentName').val(department.name);
res.redirect('/departments/add_department');
}
})
});
You could try changing the input field in handlebars to display the value you queried from mongoose
change this
<td><input class="form-control" type="text" placeholder="Department Name" name="departmentName" id="departmentName"></td>
to this
<td><input class="form-control" type="text" value={{name}} name="departmentName" id="departmentName"></td>
Then take this out of the routes
$('#departmentName').val(department.name);
UPDATE:
So something like this
// List of departments
router.get('/add_department', userAuthenticated, function(req, res, next) {
// grab the deparment from the req
var departmentFromEdit ="";
if(req.query.dn){
departmentFromEdit = req.query.dn;
}
Departments.find(function(err, departments) {
if (err) {
throw err;
}
res.render('add_department', {title:'Add New Department', departments: departments, name: departments.name, id: departments._id})
})});
// Edit department
router.get('/edit_department/:id', userAuthenticated, function(req, res, next) {
var departmentName = "";
Departments.findById(req.params.id).exec(function(err, department) {
if (err) {
throw err;
} else {
departmentName = encodeURI(department.name);
// dn for departmentName or defaultName
res.redirect('/departments/add_department?dn=' + departmentName);
}
})});

Resources