trying to display data queried from mongo db via nodejs to html index.html.
What the script does? it open the server connection , connect to mongodb and from the webform with datapicker it display the result query, via console i can see the result and it is working perfectly, now i need to display the data to web.
So far no result. Any suggestion?
var express = require("express");
var app = express();
var router = express.Router();
var path = __dirname + '/views/';
var fs = require("fs");
const util = require('util')
//lets require/import the mongodb native drivers.
var mongodb = require('mongodb');
//We need to work with "MongoClient" interface in order to connect to a mongodb server.
var MongoClient = mongodb.MongoClient;
// Connection URL. This is where your mongodb server is running.
var url = 'mongodb://localhost/klevin';
router.use(function (req,res,next) {
console.log("/" + req.method);
next();
});
router.get("/",function(req,res){
res.sendFile(path + "index.html");
var data_e_fillimit = req.param('start_time');
//console.log(params.startDate)
console.log('Data e fillimit '+data_e_fillimit)
var data_e_mbarimit= req.param('endtime_time');
//console.log(params.startDate)
console.log('Data e mbarimit '+data_e_mbarimit)
// Use connect method to connect to the Server
MongoClient.connect(url, function (err, db) {
if (err) {
console.log('Unable to connect to the mongoDB server. Error:', err);
} else {
//HURRAY!! We are connected. :)
console.log('Connection established to', url);
// Get the documents collection
var collection = db.collection('frames');
//We have a cursor now with our find criteria
var cursor = collection.find({
tv: 'tematv',
date_created: {"$gte": new Date(data_e_fillimit) , "$lte": new Date(data_e_mbarimit) }});
//We need to sort by age descending
cursor.sort({_id: -1});
//Limit to max 10 records
cursor.limit(50);
//Skip specified records. 0 for skipping 0 records.
cursor.skip(0);
//Lets iterate on the result
cursor.each(function (err, doc) {
if (err) {
console.log(err);
//res.json(err);
} else {
console.log('Fetched:', doc);
// res.json({ user: 'tobi' })
}
});
}
});
});
/*router.get("/about",function(req,res){
res.sendFile(path + "about.html");
});
router.get("/contact",function(req,res){
res.sendFile(path + "contact.html");
});*/
app.use("/",router);
/*app.use("*",function(req,res){
res.sendFile(path + "404.html");
});*/
app.listen(3000,function(){
console.log("Live at Port 3000");
});
use ejs (npm install ejs --save) package try like this:
app.engine('html', require('ejs').renderFile);
app.set('view engine', 'ejs');
app.get('/', function (req, res){
res.render('index.html',{
foo:bar
});
});
now use can use this object that passed to the index.html
Related
*I understand there is a lot of code here, but I've been struggling with this problem for a long time with no joy.
Node.js app with Express, MySQL database and EJS templating engine. I'm a total newbie.
I have a javaScript (getScoresData.js) file that returns data from MySQL database and contains code that creates a JavaScript object. This object contains values I need to send to front end (to create a data chart). The code returns the object to console when I run getSCoresData.js file so I know this part is working.
But, I have no idea how to properly implement this code/js file in order to send the object through my routes to the front end. I also don't know where getScoresData.js should actually sit in the project structure or how/if I should modularize the getScoresData.js file.
The structure is..
project/
app/
routes.js
config/
database.js
passport.js
models/
getScoresData.js
public/
scripts/
dataGraph.js
views/
server.js
getScoresData.js below
// db connection
var mysql = require('mysql');
var dbconfig = require('../config/database');
const connection = mysql.createConnection(dbconfig.connection);
//Sql Query
const scoreQuery = "SELECT question1, question2, question3, question4, question5, question6, question7, question8 FROM assessment_score";
//variable to hold score array
var scoreArray;
//returning the sql query
connection.query(scoreQuery, function (err, result) {
if (err) throw err;
//running getData() function
getData(result);
console.log(scoreArray);
// Slicing the array to make 8 categories
var category1 = scoreArray.slice(0,1);
var category2 = scoreArray.slice(2,3);
var category3 = scoreArray.slice(4,5);
var category4 = scoreArray.slice(6,7);
//parsing and accumlating each category score
var cat1Total = totalScore(category1);
var cat2Total = totalScore(category2);
var cat3Total = totalScore(category3);
var cat4Total = totalScore(category4);
//this is the object I want to send to client side to use in the graphData.js file
const categories = {cat1Total, cat2Total, cat3Total, cat4Total}
});
//function to turn sql result into an array of strings
function getData(result) {
Object.keys(result).forEach(function(key) {
const values = result[key];
return scoreArray = Object.values(values);
});
}
// function to parse the strings into numbers and accumulate them
function totalScore(categoryScore){
return categoryScore.reduce((accum,scoreArray) =>
{
const splitValues = scoreArray.split('/');
return {
score:accum.score + parseInt(splitValues[0]),
maxScore:accum.maxScore + parseInt(splitValues[1]),
}
},{score:0,maxScore:0}
);
}
routes.js file
I want to send the data through the /profile route so when users login they will displayed a graph of their score data on their profile.
module.exports = function(app, passport){
app.get('/', function(req, res){
res.render('index.ejs');
});
app.get('/login', function (req, res){
res.render('login.ejs', {message: req.flash('loginMessage')});
});
app.post('/login', passport.authenticate('local-login',{
successRedirect: '/profile',
failureRedirect: '/login',
failureFlash: true
}),
function(req, res){
if(req.body.remember){
req.session.cookie.maxAge = 1000 * 60 * 3;
}else{
req.session.cookie.expires = false;
}
res.redirect('/');
});
app.get('/profile', isLoggedIn, function (req, res) {
res.render('profile.ejs', {user:req.user
})
});
};
function isLoggedIn(req, res, next) {
if(req.isAuthenticated())
return next();
res.redirect('/');
});
dataGraph.js file
- where I want to use the categories object to create the graph
var ctx = document.getElementById("myChart").getContext('2d');
//Where I want to use the data sent through routes
var barTotalCategoryScores = [categories.cat1Total.score, categories.cat2Total.score, categories.cat3Total.score, categories.cat4Total.score];
var labels = ["Java & Design", "Build & Versioning"];
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: labels,
datasets: barTotalCategoryScores
}
}
});
I need display data in table from MySql database, but I dont know how it do this.
I tried found something example or example application with source code, but I nothing found.
Maybe someone help me with this?
I tried with node.js express:
var mysql = require('mysql');
var https = require('https');
var con = mysql.createConnection({
host: "https://adress to database",
user: "user",
password: "password",
database: "db"
});
con.connect(function(err) {
if (err) throw err;
console.log("Connected!");
});
But i get error:
Error: getaddrinfo ENOTFOUND
here is a simple way to get data from mySQL and export it as json:
var http = require('http');
var mysql = require('mysql');
var bodyParser = require("body-parser");
var express = require('express');
var app = express();
var pool = mysql.createPool({
host: 'db location',
user: 'username od db',
password: 'something',
database: 'yourdatabase',
port:3306
});
// define rute
var apiRoutes = express.Router();
var port = 9000;
apiRoutes.get('/', function (req, res) {
res.json({ message: 'API works' });
});
apiRoutes.get('/data', function (req, res, next) {
pool.getConnection(function (err, connection) {
if (err) {
console.error("error hapened: " + err);
}
var query = "SELECT * FROM imena ORDER BY id ASC";
var table = ["imena"];
query = mysql.format(query, table);
connection.query(query, function (err, rows) {
connection.release();
if (err) {
return next(err);
} else {
res.json({
success: true,
list_users: rows
});
}
});
});
});
app.use('/api', apiRoutes);
// starting
app.listen(port);
console.log('API radi # port:' + ' ' + port);
But i still suggest that you start using noSQL databases like firebase because of they are simple and faster.
In order to show data from MySQL Database, you need to provide application interface(s) to Angular environment and only then Angular can use the data. There are few techniques in which you can design interfaces, REST is the most popular though.
First you need to understand that Angular is Front-End framework and it can only send requests to backend such as Node js, PHP etc.Thus, first you need to chose your backend. Node is popular with express js module, but if you still don't have mySQL set, go for firebase real time database. If you decide node js => express => mySQL check tutorial online.
I have an expressjs app with the following routes and middleware modules. I am trying to test the routes module using mocha, chai, http-chai and sinonjs.
The API uses mysql and in order to test the routes module, I have it all modularized so that I can stub out the mysql module.
However when I try to stub middleware/index, I am having trouble. If I try to require index normally, the module doesn't actually get stubbed. If I try to require it using require.cache[require.resolve('./../../lib/routes/middleware/index')];, it seems to stub something, but indexStub.returns(indexObj) returns an error TypeError: indexStub.returns is not a function and TypeError: indexStub.restore is not a function.
How do I stub out index.js properly in order to control the code flow and keep it from trying to connect to mysql?
routes.js
'use strict';
const express = require('express');
const router = express.Router();
const configs = require('./../config/configs');
const middleware = require('./middleware/index');
const bodyParser = require('body-parser');
const useBodyParserJson = bodyParser.json({
verify: function (req, res, buf, encoding) {
req.rawBody = buf;
}
});
const useBodyParserUrlEncoded = bodyParser.urlencoded({extended: true});
// creates a new post item and return that post in the response
router.post('/posts', useBodyParserUrlEncoded, useBodyParserJson, middleware.validatePostData, middleware.initializeConnection, middleware.saveNewPost, middleware.closeConnection, function(req, res) {
if (res.statusCode === 500) {
return res.send();
}
if (res.statusCode === 405) {
return res.send('Item already exists with slug ' + req.body.slug + '. Invalid method POST');
}
res.json(res.body).end();
});
module.exports = router;
middleware/index.js
'use strict';
const configs = require('./../../config/configs');
const database = require('./../../factories/databases').select(configs.get('STORAGE'));
const dataV = require('./../../modules/utils/data-validator');
module.exports = {
initializeConnection: database.initializeConnection, // start connection with database
closeConnection: database.closeConnection, // close connection with database
saveNewPost: database.saveNewPost, // creates and saves a new post
validatePostData: dataV.validatePostData, // validates user data
};
spec-routes.js
'use strict';
var chai = require('chai');
var chaiHttp = require('chai-http');
var sinonChai = require("sinon-chai");
var expect = chai.expect;
var sinon = require('sinon');
chai.use(sinonChai);
chai.use(chaiHttp);
var app = require('./../../app');
describe('COMPLEX ROUTES WITH MIDDLEWARE', function() {
var indexM = require.cache[require.resolve('./../../lib/routes/middleware/index')];
describe('POST - /posts', function() {
var indexStub,
indexObj;
beforeEach(function() {
indexStub = sinon.stub(indexM);
indexObj = {
'initializeConnection': function(req, res, next) {
return next();
},
'closeConnection': function(req, res, next) {
return next();
},
'validatePostData': function(req, res, next) {
return next();
}
};
});
afterEach(function() {
indexStub.restore();
});
it('should return a 500 response', function(done) {
indexObj.saveNewPost = function(req, res, next) {
res.statusCode = 500;
return next();
};
indexStub.returns(indexObj);
chai.request(app)
.post('/posts')
.send({'title': 'Hello', 'subTitle': 'World', 'slug': 'Example', 'readingTime': '2', 'published': false})
.end(function(err, res) {
expect(res).to.have.status(500);
done();
});
});
});
});
You don't use Sinon at all, as it doesn't deal with module loading at all. I see you have started doing this manually using the internal Node API's, but I suggest you do it the way we advise in the Sinon docs regarding this usecase: juse use proxyquire.
It enables you to substitute require calls to ./middleware/index.js for a mock object of your own liking (possibly made using sinon).
You would use it something like this:
var myIndex = {
initializeConnection: sinon.stub(),
closeConnection: sinon.stub(),
saveNewPost: sinon.stub()
};
var app = proxyquire('./../../app', {'./middleware/index': myIndex});
In the following code, I am trying to retrieve data from MySQL database and show them to a user by using response write. The error that I got is Error: write after end:
var http = require("http");
var mysql = require('mysql');
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var urlencodedParser = bodyParser.urlencoded({ extended: false })
app.use(express.static('public'));
app.get('/Search.html', function (req, res) {
res.sendFile( __dirname + "/" + "Search.html" );
})
var connection = mysql.createConnection(
{
host : 'localhost',
user : 'root',
password : 'somepass',
database : 'SocialQuery',
}
);
connection.connect();
app.post('/process_post', urlencodedParser, function (req, res) {
// Prepare output in JSON format
response = {
SearchType:req.body.SearchTypes,
Term:req.body.term
};
//var vas = JSON.stringify(response);
var search = req.body.SearchTypes;
var term = req.body.term;
var query = connection.query('Select * from ?? where Lable = ?', [search, term], function(err, rows) {
res.write(rows);
});
console.log(query.sql);
res.end();
})
//}).listen(8081);
http.createServer(app).listen(8081);
console.log('Server running at http://127.0.0.1:8081/');
I changed res.write(rows); to res.end(rows); but didn't work. Can someone help me solving this problem.
The problem is that MySQL queries are asynchronous in node.js. so, the result won't be in the variable query, but retrieved in the callback, to the variable rows. So what happens is that res.end() is called, and then the callback returns and res.write() is called, so it's called after end().
You are doing an Asynchronous call when fetching data from database. res.write() is inside callback function so before fetching data it would call res.end() and res.write() will be called after the data has been fetched. That's why you are getting Error: write after end . You can use res.end() in the same callback function.
var query = connection.query('Select * from ?? where Lable = ?', [search, term], function(err, rows) {
res.write(rows, function(err){
res.end();
});
});
Now the res.end() function will be called after the write process has been done.
It worked after I made two changes:
var query = connection.query('Select * from ?? where Lable = ?', [search, term], function(err, rows) {
console.log(rows);
res.write(JSON.stringify(rows));
res.end();
});
First, I moved res.end(); inside the connection.query part.
Second, instead of writing rows only, I changed to res.write(JSON.stringify(rows));
I dont understand why I cant display my json data. I am new to javascript and I want to display the data in the json file to my index file.
I have used the express generator for all the files. I did read that I should add this FS code in my app.js, but I cant use the data variable in my index file in my view. Any help ?
var express = require('express');
var router = express.Router();
var fs = require('fs');
/* GET home page. */
router.get('/', function(req, res, next) {
var file = __dirname + '/public/list/list.json';
var data;
fs.readFile(file, 'utf8', function (err, data) {
if (err) {
console.log('Error: ' + err);
return;
}
data = JSON.parse(data);
console.log(data);
});
res.render('index', { title: data });
console.log(data);
});
module.exports = router;
here is my json file
{
"username":"xyz",
"password":"xyz#123",
"email":"xyz#xyz.com",
"uid": 1100
}
fs.readFile is asynchronous , so you should put res.render(..) inside his callback , because it will fired when the readFile function ends. So change your code to :
fs.readFile(file, 'utf8', function (err, data) {
if (err) {
console.log('Error: ' + err);
return;
}
data = JSON.parse(data);
console.log(data);
res.render('index', { title: data });
});
The above answer is correct, but there's also an alternative.
If you're using this file for your index page, it'd be used a lot. If the data isn't changing, you can simply require the JSON file at the top of your code and return it in the request.
var express = require('express');
var router = express.Router();
var list = require(__dirname + '/public/list/list.json');
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: list });
});
module.exports = router;
However, if that data does change frequently, reading the file is the way to go.