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>
Related
I want to pass data from MySQL database in datalist option. My application is written in express js using ejs view. I can't figure out how to pass database values to list in JavaScript and how to pass this list to ejs file.
add.js:
module.exports = {
addProductPage: (req, res) => {
let query = "SELECT shipper_names.Shipper_ID, shipper_names.Shipper_Name FROM shipper_names";
conn.query(query, (err, results) => {
if (err) {
return res.status(500).send(err);
}
res.render('add-product.ejs', {
title: "Add Product",
shipper_names: results[0],
message: ''
});
});
}
}
EJS file:
<!doctype html>
<html lang="en">
<div>
<a class="float-right" href="/" title="Home">Home</a>
</div>
<div class="contnainer">
<% if (message) {%>
<p class="text-container text-danger">
<%= message %>
</p>
<%}%>
<% if (shipper_names) {%>
<form class="add-player-form" action="" method="POST" enctype="multipart/form-data">
<div>
<input type="text" id="shippers_names" list="languageList" />
<!--your input textbox-->
<datalist id="languageList">
<option value=""> </option>
</datalist>
</div>
<button type="submit" class="btn">Add Product</button>
</form>
<% } else { %>
<p class="text center">Product Not Found. Go HereTo Add Product.</p>
<% } %>
</div>
</html>
module.exports = {
addProductPage: (req, res) => {
let query = "SELECT * from shipper_names"
conn.query(query, (err, results) => {
if (err) {
return res.status(500).send(err);
}
res.render('add-product.ejs', {
shipper_names: results
});
});
},
<div>
<input type="text" id="txtAutoComplete" list="names" />
<!--your input textbox-->
<datalist id="names">
<% shipper_names.forEach((shipper_names, index)=>{%>
<option id=<%= shipper_names.Shipper_ID%>>
<%= shipper_names.Shipper_Name%></option>
<%})%>
</datalist>
</div>
this is working
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
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>
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);
}
})});
**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}