I've made an nodeJS app with express. I am able to retrieve data from google analytics, however I'm not able to show the data on the screen, since the authorization/google analytics api is asynchronous.
Can someone help me with writing a function with callback, which will update a div called '.report' index page and show the JSON inside the div.
javascripts/googleAuth.js
var google = require('googleapis');
var path = require("path");
var getJWTClient = {
authorize: function () {
var jwtClient = new google.auth.JWT(
'cboboekverkoperdashboardv2#clear-style-185306.iam.gserviceaccount.com',
path.join(__dirname, '../.', '/files/KEY.json'),
null,
['https://www.googleapis.com/auth/analytics.readonly'] //scope
);
jwtClient.authorize(function (err, tokens) {
console.log('jwtClient.authorize() started');
if (err) {
console.log('error in authorization:' + err);
return;
} else {
console.log('authorization success!');
var analytics = google.analytics('v3');
return queryData(analytics,jwtClient);
}
})
}
}
function queryData(analytics,jwtClient){
var VIEW_ID = 'ga:163754738';
analytics.data.ga.get({
'auth': jwtClient,
'ids': VIEW_ID,
'metrics': 'ga:uniquePageviews',
'dimensions': 'ga:pagePath',
'start-date': '30daysAgo',
'end-date': 'yesterday',
'sort': '-ga:uniquePageviews',
'max-results': 10,
}, function (err, response) {
if (err) {
console.log(err);
return;
}
console.log(JSON.stringify(response, null, 4));
// should be able to update the .report on index page with this information.
return JSON.stringify(response, null, 4);
});
}
module.exports = getJWTClient;
My app.js
var express = require('express');
var path = require('path');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var index = require('./routes/index');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', index);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
index.pug
extends layout
block content
h1= title
p Welcome to #{title}
div(class='report') #{jsonReport}
Routing/index.pug
var express = require('express');
var router = express.Router();
var googleAuth = require('../public/javascripts/googleAuth.js');
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Dashboard', jsonReport: googleAuth.authorize() });
});
module.exports = router;
Related
I am trying to pass html from a client(angularjs) app to server side (nodejs), i am trying to access the html via the req.body, but the object is always empty({}).
So on the client side, I just call the api passing the html:
generatePDF() {
const htmlBlock = document.getElementById("templateArea");
const htmlObj = {"element": htmlBlock};
this.pdfService.generatePDF(htmlObj).subscribe(
(response) => {
console.log("pdf generated");
},
(error) => {
console.log(error);
}
);
}
the angular service does a post call.
everything fine, since it reaches the api, but then i try to access via console.log the req.body, that shows me always empty, any suggestion (i have the bodyparser already).
my app.js
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var router = express.Router();
var app = express();
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.all('/*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept")
next();
});
app.use('/',require('./routes/index'));
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
the route:
var express = require('express');
var router = express.Router();
var pdfGenerator = require('../controllers/pdfGenerator');
router.post('/pdfURL', pdfGenerator.pdfToUrl );
module.exports = router;
the controller
var express = require('express');
var router = express.Router();
var fs = require('fs');
var pdf = require('html-pdf');
//var html = fs.readFileSync('./test/businesscard.html', 'utf8');
var options = { format: 'Letter' };
module.exports = {
pdfToUrl: function(req,res,next) {
console.log(req.body);
pdf.create('<div style="background-color:blue">a simple text</div>', options).toFile('./businesscard.pdf', function(err, res) {
console.log("asd"); // { filename: '/app/businesscard.pdf' }
if (err) return console.log(err);
console.log("asd"); // { filename: '/app/businesscard.pdf' }
});
}
};
I am learning Node.js through a tutorial to build a simple API.
I have my own postgres db and I am trying to retrieve a table and not use the sample db/dummy db in the tutorial. I am following everything in the tutorial, only thing is I am using my own db and getting 404 not found error.
My Index.js
var express = require('express');
var router = express.Router();
var db = require('../queries');
router.get('/api/preference', function(req,res){ res.send('hi'); })
module.exports = router;
Queries.js
var promise = require('bluebird');
var options ={
//Initialization options
promiseLib : promise
};
var pgp = require('pg-promise')(options);
var db = pgp({
host: 'localhost',
port: 5432,
database: 'pmc',
user: 'tarun',
password: 'pes'
});
var connectionstring = 'postgres://tarun:pes#localhost:5432/pmc';
var db = pgp(connectionstring);
//add query funtions
module.exports = {
getAllPreference : getAllPreference
};
function getAllPreference(req,res,next){
db.any('select * from core.preferences')
.then(function(data){
res.status(200)
.json({
status : 'success',
data : data,
message: 'Retrieved ALL preferences'
});
})
.catch(function (err) {
return next(err);
});
}
app.js
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var index = require('./routes/index');
var users = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', index);
app.use('/users', users);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
Error
Error: Not Found
at D:\node-postgress-promises\app.js:32:13
at Layer.handle [as handle_request] (D:\node-postgress-promises\node_modules\express\lib\router\layer.js:95:5)
at trim_prefix (D:\node-postgress-promises\node_modules\express\lib\router\index.js:317:13)
at D:\node-postgress-promises\node_modules\express\lib\router\index.js:284:7
at Function.process_params (D:\node-postgress-promises\node_modules\express\lib\router\index.js:335:12)
at next (D:\node-postgress-promises\node_modules\express\lib\router\index.js:275:10)
at D:\node-postgress-promises\node_modules\express\lib\router\index.js:635:15
at next (D:\node-postgress-promises\node_modules\express\lib\router\index.js:260:14)
at Function.handle (D:\node-postgress-promises\node_modules\express\lib\router\index.js:174:3)
at router (D:\node-postgress-promises\node_modules\express\lib\router\index.js:47:12)
Blockquote
Change this portion of code as follow
exports.getAllPreference = function(req,res,next){
console.log('h');
db.any('select * from core.preferences')
.then(function(data){
res.status(200)
.json({
status : 'success',
data : data,
message: 'Retrieved ALL preferences'
});
})
.catch(function (err) {
next(err);
});
}
Remove below code in this file
module.exports = {
getAllPreference= getAllPreference
}
Change your index.js file Remove below lines
module.exports = {
getAllPreference: getAllPreference
};
function getAllPreference(req, res, next) {};
And uncomment
module.exports = router;
Add below code for testing purpose. in index.js file
router.get('/api/preference', function(req,res){
res.send('hi');
};
I wrote a script which save an object to a MongoDB database using mongoose. The object is correctly save to the database, but the server crashes right after, throwing me the following error message: catch(err) { process.nextTick(function() { throw err}); }
Here's a part of my code:
users.js
var User = require('../models/user');
router.post('/register', function(req, res, next) {
[...]
// checks for errors
var errors = req.validationErrors();
if (errors) {
res.render('register', {
errors: errors,
[...]
})
} else {
var newUser = new User({
[...]
});
// Create user
User.createUser(newUser, function(err, user) {
if (error) {
throw err;
};
console.log(user);
});
[...]
}
});
module.exports = router;
user.js
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/nodeauth');
// User Schema
var UserSchema = mongoose.Schema({
[...]
});
var User = module.exports = mongoose.model('User', UserSchema);
module.exports.createUser = function(newUser, callback) {
newUser.save(callback);
}
apps.js
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var session = require('express-session');
var passport = require('passport');
var localStrategy = require('passport-local').Strategy;
var bodyParser = require('body-parser');
var multer = require('multer');
var flash = require('connect-flash');
var mongo = require('mongodb');
var mongoose = require('mongoose');
var db = mongoose.connection;
var expressValidator = require('express-validator');
var routes = require('./routes/index');
var users = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// handle file uploads
app.use(multer({dest:'./uploads'}).single('singleInputFileName'));
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
// handle express session
app.use(session({
secret: 'secret',
saveUninitialized: true,
resave: true
}));
// passport
app.use(passport.initialize());
app.use(passport.session());
// validator
app.use(expressValidator({
errorFormatter: function(param, msg, value) {
var namespace = param.split('.')
, root = namespace.shift()
, formParam = root;
while(namespace.length) {
formParam += '[' + namespace.shift() + ']';
}
return {
param : formParam,
msg : msg,
value : value
};
}
}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
// connect flash
app.use(flash());
app.use(function (req, res, next) {
res.locals.messages = require('express-messages')(req, res);
next();
});
app.use('/', routes);
app.use('/users', users);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
module.exports = app;
You shouldn't throw error you should return it in handler to let clients know if there is a database error creating the user. Only throw when caller can catch error, async code cannot be caught easily. Promises enable throwing errors but not callbacks.
I am developing an application in Express Js. When I try to run the application I get this error:
My app.js file is like this:
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var routes = require('./routes/index');
var users = require('./routes/users');
var app = express();
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/users', users);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
var server = app.listen(3000, function() {
var host = server.address().address;
var port = server.address().port;
console.log('Example app listening at http://%s:%s', host, port);
});
module.exports = router;
My index.js is like this:
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function (req, res, next) {
res.render('index', {title: 'Polls'});
});
router.get("/list", function (req, res, next) {
Poll.find({}, 'question', function (error, polls) {
res.json(polls);
});
});
router.get("/poll", function (req, res, next) {
var pollId = req.params.id;
// Find the poll by its ID, use lean as we won't be changing it
Poll.findById(pollId, '', {lean: true}, function (err, poll) {
if (poll) {
var userVoted = false,
userChoice,
totalVotes = 0;
// Loop through poll choices to determine if user has voted
// on this poll, and if so, what they selected
for (c in poll.choices) {
var choice = poll.choices[c];
for (v in choice.votes) {
var vote = choice.votes[v];
totalVotes++;
if (vote.ip === (req.header('x-forwarded-for') || req.ip)) {
userVoted = true;
userChoice = {_id: choice._id, text: choice.text};
}
}
}
// Attach info about user's past voting on this poll
poll.userVoted = userVoted;
poll.userChoice = userChoice;
poll.totalVotes = totalVotes;
res.json(poll);
} else {
res.json({error: true});
}
});
});
router.get("/create", function (req, res, next) {
var reqBody = req.body,
// Filter out choices with empty text
choices = reqBody.choices.filter(function (v) {
return v.text != '';
}),
// Build up poll object to save
pollObj = {question: reqBody.question, choices: choices};
// Create poll model from built up poll object
var poll = new Poll(pollObj);
// Save poll to DB
poll.save(function (err, doc) {
if (err || !doc) {
throw 'Error';
} else {
res.json(doc);
}
});
});
module.exports = router;
And user.js is this:
var express = require('express');
var router = express.Router();
/* GET users listing. */
router.get('/', function(req, res, next) {
res.send('respond with a resource');
});
module.exports = router;
I tried to find my solution on SO, but couldn't. Feel free to tell me if i need to provide any other file. Any help?
You should define routes in your index.js like you do in user.js.
app.use('/', routes) in your code expects routes to be an instance of a Router, but you're exporting an object with functions instead of that.
So your index.js file should have the following structure:
var express = require('express');
var router = express.Router();
router.get("/", function (req, res) {
res.render('index');
});
router.get("/list", function(req, res) {/*list implementation*/});
....
module.exports = router;
I'm experiencing extremely long TTFB on my localhost node/express server.
On average each request's(including static resource) TTFB is around 1s, occasionally up to 7s(I guess this is NOT normal)
What could cause this long TTFB and how to improve?
Could it be my fault for configing express wrong?
Here is my app.js:
var express = require('express');
var path = require('path');
var bodyParser = require('body-parser');
var methodOverride = require('method-override');
var favicon = require('serve-favicon');
var morgan = require('morgan')
//Router files
var all = require('./api/all');
var admin = require('./api/admin');
var student = require('./api/student');
var teacher = require('./api/teacher');
var course = require('./api/course');
var forum = require('./api/forum');
var group = require('./api/group');
var board = require('./api/board');
// App Setup
var app = express();
// View engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(morgan(':remote-addr [:date[clf]] :user :method :url :status :response-time ms',{
skip: function (req, res) {
//var noUser = (req.AV.user === undefined);
//return noUser;
return true;
}
}));
app.use(favicon(__dirname + '/public/favicon.ico'));
// Load Cloud Code
//app.use(cloud);
//Express Middleware
app.use(methodOverride('_method'))
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(__dirname+'/public'));
//The Route
app.get('/', function(req, res) {
res.send('./public/index.html');
});
//Routers
app.use('/api',all);
app.use('/api/admin',admin);
app.use('/api/student',student);
app.use('/api/teacher',teacher);
app.use('/api/course',course);
app.use('/api/forum',forum);
app.use('/api/group',group);
app.use('/api/board',board);
//404 Handler
app.use(function(req, res, next) {
//console.log("NOT FOUND: "+req.url);
var err = new Error('Not Found');
err.status = 404;
res.render('notfound.jade');
//next(err);
});
// error handlers for different env
if (app.get('env') === 'development') {
console.log("dev env");
app.use(function(err, req, res, next) {
res.status(err.status || 500);
if(res.status===500){
console.log(err);
//console.log(err.stack.split("\n"));
}
res.send({
message: err.message,
error: err
});
});
}
app.use(function(err, req, res, next) {
res.status(err.status || 500);
console.log(err.message);
res.send({
message: err.message,
error: {}
});
});
module.exports = app;
ps:I'm using node 4.0.0 and latest chrome