Generating a PDF file using data from MySQL database in Node js - mysql

I am trying to generate a PDF file using the data stored in the Mysql database using Node js, Pdfkit and pdfkit-table. I need to print the records in database to a table in the PDF document.
The below code generates an empty PDF file. Please help me to solve the problem of why it does not generate a PDF file with data.
This is index.js file.
var express = require('express');
var router = express.Router();
var PDFDocument = require('pdfkit');
var orm = require('orm');
var PDFDoc = require("pdfkit-table");
router.use(orm.express("mysql://root:#localhost:/kirula_fashion", {
define: function (db, models, next) {
models.news = db.define("ledger", {
id : String,
date : String,
description : String,
debit : String,
credit : String,
});
next();
}
}));
router.get('/', function(req, res, next) {
var result = req.models.news.find({
}, function(error, news){
if(error) throw error;
res.render('index', { news:news, title: 'Generate PDF using NodeJS'
});
});
});
router.get('/pdf', function(req, res, next) {
var id = req.query.id;
const doc = new PDFDocument();
const docTable = new PDFDoc();
var result = req.models.news.find({id: id}, function(error, newspost){
if(error) throw error;
else{
if(newspost.length>0){
for(var i=0; i<newspost.length;i++){
var date = newspost[0]['date'];
var description = newspost[0]['description'];
var debit = newspost[0]['debit'];
var credit = newspost[0]['credit'];
var table = {
title: "Ledger records",
subtitle: "May - 2020",
headers: [
{ "label":"Date", "property":"date", "width":100 },
{ "label":"Description", "property":"description", "width":100 },
{ "label":"Debit", "property":"debit", "width":100 },
{ "label":"Credit", "property":"credit", "width":100 }
],
datas:
[
{ "date":date, "description":description, "debit":debit, "credit":credit},
{
"renderer": "function(value, i, irow){ return value + `(${(1+irow)})`; }"
}
],
};
docTable.table( table, {
width: 300,
});
}
}
}
var title = "Ledger for May 2020";
var filename = encodeURIComponent(title) + '.pdf';
res.setHeader('Content-disposition', 'attachment; filename="' + filename + '"');
res.setHeader('Content-type', 'application/pdf');
doc.pipe(res);
doc.end();
});
});
module.exports = router;

I encounter the same issue with datas options, however with rows options pdfkit-table work nicely, maybe mapping from [{..},{...}] to [[..],[...]] then use rows option

Related

use common function output in multple files in node.js

I am new to programming...still self learning. I have below problem
I have below code in x.js file which I wish to reuse in same x.js file as well as in y.js file. both x.js and y.js are in controllers folder in a node.js project. The code is
''''''''
let indexmain = function(){
async.parallel({branch_count(callback) {
Branch.countDocuments({}, callback); documents of this collection},
customer_instance_count(callback) {
CustInstance.countDocuments({}, callback);
},
customer_instance_available_count(callback) {
CustInstance.countDocuments({ status:'Interested' }, callback);
},
}
);
return [branch_count, customer_instance_count, customer_instance_available_count];
''''''''
When used in below code inthe same file:
''''''''
const { body, validationResult } = require("express-validator");
const Branch = require('../models/brdetails');
const Customer = require('../models/custdetails');
const CustInstance = require('../models/custInstance');
const async = require('async');
exports.index = (req,res) => { (
branch_count = Indexmain[0],
customer_instance_count = Indexmain[1],
customer_instance_available_count = Indexmain[2]);
(err, results, next) => { if (err) { return next(err); }
res.render('index.jade', {error: err, data: results });
}
};
'''
There is no error, but page does not load at all. When checked with
'''
console.log("Indexmain is", Indexmain[0]);
'''
Output is "Indexmain is undefined".
What is to be done? Please help.

How do I send the data I've got from db from Node.js through routes to front-end JavaScript file?

*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
}
}
});

Why does a loaded CSV set the value of object to a string

So I have this code:
function _getAllArticles() {
var result = [];
result.push(new Article('./BatmanEpicWallpaper.jpg','Batman','A poster of batman', 100, 34.99));
result.push(new Article('./BatmanEpicWallpaper.jpg', 'Batman2', 'A poster of batman2', 10, 124.99));
result.push(new Article('./BatmanEpicWallpaper.jpg', 'Batman3', 'A poster of batman3', 25, 4.99));
var converter = require('json-2-csv');
var fs = require('fs')
var test = [];
converter.json2csv(result, function (err, csv) {
if (err) console.log(err);
console.log(csv);
test.push(csv);
})
fs.writeFile('file.csv', test, function (err) {
if (err) throw err;
console.log('file saved');
});
var fs = require('fs')
var csvjson = require('csvjson');
var data = fs.readFileSync('file.csv', { encoding: 'utf8' });
return csvjson.toObject(data);
}
As you can see I have object article where there are two attributes with numbertypes. But when I load the file the values of the attributes quantity and price are converted to a string. When I exceute this line of codereturn csvjson.toObject(data); and JSON.stringify it I get this:
[{"imageLocation":"./BatmanEpicWallpaper.jpg","title":"Batman","description":"A poster of batman","quantity":"34.99","price":"100"},{"imageLocation":"./BatmanEpicWallpaper.jpg","title":"Batman2","description":"A poster of batman2","quantity":"124.99","price":"10"},{"imageLocation":"./BatmanEpicWallpaper.jpg","title":"Batman3","description":"A poster of batman3","quantity":"4.99","price":"25"}]
As you can see the value of the attribute quantity and price are always with "" why is that so? Is it because of modules which I use (json-2-csv,csvjson)?
Here is where I stringify it:
GetAllArticles: (req, res) => {
var allArticles = _getAllArticles();
res.setHeader("Content-Type", 'application/json');
res.write(JSON.stringify(allArticles));
res.end();
},

Node.js : Write new data to an existing json file

I'm trying to add data to an existing json file (codes below). When I access the locahost, the new piece of data shows up, however, when I check the data (users.json), the new piece of data (i.e. user4) isn't there.
Does anyone know what's wrong with the code? Thank you!
var express = require('express');
var app = express();
var fs = require("fs");
var user = {
"user4" : {
"name" : "mohit",
"password" : "password4",
"profession" : "teacher",
"id": 4
}
}
app.get('/addUser', function (req, res) {
// First read existing users.
fs.readFile( __dirname + "/" + "users.json", 'utf8', function (err, data) {
data = JSON.parse( data );
data["user4"] = user["user4"];
console.log( data );
res.end( JSON.stringify(data));
});
})
var server = app.listen(8081, function () {
var host = server.address().address
var port = server.address().port
console.log("Example app listening at http://%s:%s", host, port)
})
EDIT:
I added fs.writeFile(...) (codes below). After running the code, the only content of the uers.json file is:utf8
var express = require('express');
var app = express();
var fs = require("fs");
var user = {
"user4" : {
"name" : "mohit",
"password" : "password4",
"profession" : "teacher",
"id": 4
}
}
app.get('/addUser', function (req, res) {
// First read existing users.
fs.readFile( __dirname + "/" + "users.json", 'utf8', function (err, data) {
data = JSON.parse( data );
data["user4"] = user["user4"];
console.log( data );
// res.end( JSON.stringify(data));
data = JSON.stringify(data);
fs.writeFile(__dirname+"/"+"users.json", "utf8", function(err,data){
if (err){
console.log(err);
};
res.end(data);
});
});
})
To write to a file you should use fs.writeFile.
fs.writeFile(__dirname + "/" + "users.json", user["user4"], 'utf8', function()
{
// do anything here you want to do after writing the data to the file
});
I have passed data to writeFile so that it may write the information in data variable to JSON
fs.readFile( __dirname + "/" + "users.json", 'utf8', function (err, data) {
data = JSON.parse( data );
data["user4"] = user["user4"];
console.log( data );
data = JSON.stringify(data);
fs.writeFile(__dirname + "/" + "users.json", data , 'utf8', function(err,data) {
if (err){
console.log(err);
};
res.end(data);
});
});

Data not getting saved in the MongoDB from node.js

I want to create the rest api using node.js and mongodb
I am entering all the details and trying it to store it in the mongodb database.
// call the packages we need
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
var morgan = require('morgan');
// configure app
app.use(morgan('dev')); // log requests to the console
// configure body parser
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
var port = process.env.PORT || 8080; // set our port
var mongoose = require('mongoose');
// mongoose.connect('mongodb://node:node#novus.modulusmongo.net:27017/Iganiq8o'); // connect to our database
mongoose.connect('mongodb://localhost:27017');
var Bear = require('./app/models/bear');
// create our router
var router = express.Router();
// middleware to use for all requests
router.use(function(req, res, next) {
// do logging
console.log('Something is happening.');
next();
});
// test route to make sure everything is working (accessed at GET http://localhost:8080/api)
router.get('/', function(req, res) {
res.json({ message: 'hooray! welcome to our api!' });
});
// on routes that end in /bears
// ----------------------------------------------------
router.route('/bears')
// create a bear (accessed at POST http://localhost:8080/bears)
.post(function(req, res) {
var bear = new Bear(); // create a new instance of the Bear model
bear.name = req.body.name; // set the bears name (comes from the request)
bear.email= req.body.email; // set the bears email(comes from the request)
bear.save(function(err) {
if (err)
res.send(err);
res.json({ message: 'Bear created!' });
});
})
// get all the bears (accessed at GET http://localhost:8080/api/bears)
.get(function(req, res) {
Bear.find(function(err, bears) {
if (err)
res.send(err);
res.json(bears);
});
});
// on routes that end in /bears/:bear_id
// ----------------------------------------------------
router.route('/bears/:bear_id')
// get the bear with that id
.get(function(req, res) {
Bear.findById(req.params.bear_id, function(err, bear) {
if (err)
res.send(err);
res.json(bear);
});
})
// update the bear with this id
.put(function(req, res) {
Bear.findById(req.params.bear_id, function(err, bear) {
if (err)
res.send(err);
bear.name = req.body.name;
bear.save(function(err) {
if (err)
res.send(err);
res.json({ message: 'Bear updated!' });
});
});
})
// delete the bear with this id
.delete(function(req, res) {
Bear.remove({
_id: req.params.bear_id
}, function(err, bear) {
if (err)
res.send(err);
res.json({ message: 'Successfully deleted' });
});
});
// REGISTER OUR ROUTES -------------------------------
app.use('/api', router);
// START THE SERVER
// =============================================================================
app.listen(port);
console.log('Magic happens on port ' + port);
The Model is given below:-
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var BearSchema = new Schema({
name: String,
email: String
});
module.exports = mongoose.model('Bear', BearSchema);
I am trying it to save the name and the email in the mongodb database but only _id is created instead of name, email.
Here is the result:-
[
{
"_id": "567f1f92db24304013000001",
"__v": 0
},
{
"_id": "567f2765db24304013000002",
"__v": 0
}
]
Can anybody tell me why the data are not getting saved in the database.
Please kindly help.
Thanks in Advance.
I think your POST request is not good, so I made this simple script to check it out:
var XHR = (function() {
var _xhr = (function() {
try {
return new(this.XMLHttpRequest || ActiveXObject)('MSXML2.XMLHTTP.3.0');
} catch (e) {}
})();
return function(method, url, params, callback) {
_xhr.onreadystatechange = function() {
if (_xhr.readyState == 4) {
var _response;
try {
_response = JSON.parse(_xhr.response);
} catch (e) {
_response = _xhr.responseText;
}
if (_xhr.status != 200) {
// catch an error
console.error('error', response);
} else {
if (callback) {
callback(_response);
} else {
// deal with it
}
}
}
}
if (!params) {
params = JSON.stringify({});
} else {
params = JSON.stringify(params);
}
_xhr.open(method, url, true);
// just json in this case
_xhr.setRequestHeader("Content-type", "application/json;charset=UTF-8");
_xhr.send(params);
};
})();
fire it up in browser's console, like this
XHR('POST','api/bears', { name:'yogi', email:'yogi#bears.com'}, function(){ console.log(arguments) });
and your record will be saved.
{ "_id" : ObjectId("567e875d068748ee5effb6e0"), "email" : "yogi#bears.com" "name" : "yogi", "__v" : 0 }
Long story short - your code is okay, your POST is not.