I'm trying to return a file as a response to a GET request using express.js
I wrote a simple FileManager class to handle file request, however i'm getting the 'undefined is not a function' error ,when I call new FileManager()
Here's, how I try to do this:
//FileManager.js
FileManager = function () {}; //Empty initializer
FileManager.prototype.handleFileRequest = function(req,res){
var fileId = req.params.id
if(fileId){
var path = './uploads/events' + fileId;
res.sendfile(path)
} else {
res.send(404, 'file not found')
}
}
Here's the server:
//server.js
var express = require('express');
var FileManager = require('./FileManager.js').FileManager;
var app = express();
var fileman = new FileManager();
app.get('/:id', function (req, res){
console.log('get id:' + req.params.id);
fileman.handleFileRequest(req,res);
})
app.listen('blabla',3000);
but when I run node server.js , i get the following error:
var fileman = new FileManager();
^
TypeError: undefined is not a function
In FileManager.js ... you need to export the object.
module.exports = {
FileManager : FileManager
}
server.js
var FileManager = require('./FileManager.js').FileManager;
// this has the FileManager object that was created in the FileManager.js
Related
I am troubling with nodejs proxy server modified(write) response.
I want to achieve auto login for one site via node proxy server and for that i have to query in database then i can modified response but it seems req ended before req.write and getting Error: write after end
Below is my implementation so far.
var express = require('express');
var proxy = require('http-proxy-middleware');
var options = {
target: 'http://example.com/', // target host
changeOrigin: true,
onProxyReq: function onProxyReq(proxyReq, req, res) {
var _write = res.write;
var body = "";
proxyReq.on('data', function(data) {
data = data.toString('utf-8');
body += data;
});
res.write = function (data) {
try{
//I have database query here instead of setTimeout
setTimeout(function(){
/* Modified response here and write */
_write.call(res, data); //can't write because req already end
},3000);
} catch (err) {
console.log('err',err);
}
}
}
}
// create the proxy (without context)
var exampleProxy = proxy(options);
// mount `exampleProxy` in web server
var app = express();
app.use('/', exampleProxy);
app.listen(8080);
Can anyone guide me how to achieve this ?
I'm building my first node/express app and am following this tut.
I am at a point where I am trying to get all JSON data and put it in an array to be sent to the template and rendered. When I try to run the app via CLI, I get the following error:
Directory Structure
The data output at the var blogsurlall location
hellotest.js
var routes = require('./routes/index');
var express = require('express');
var app = express();
var request = require("request");
var blogsurlall = "https://[JSON export URL location configured in a Drupal 8 view]";
app.set('view engine','ejs');
var server = app.listen (2000, function(){ console.log('Waiting for you on port 2000'); });
/* Get all global blogs data */
request({
url: blogsurlall,
json: true
}, function (error, response, body) {
if (!error && response.statusCode === 200) {
blogsdata_all = body;
}
// Create blogs array for footer.
var blogs = [];
// Fill up the array with blogs.
blogsdata_all.blogs.forEach(function(item){
blogs = blogs.concat(item);
});
app.locals.blogsdata = blogs;
});
app.use('/', routes);
index.js
var express = require('express');
var routes = express.Router();
routes.get('/', function(req, res){ res.render('default',{title: 'Home', body: 'blogsdata'}); });
routes.get('/about-us', function(req, res){ res.send('<h1>Lucius Websystems</h1>Amsterdam, The Netherlands'); });
routes.get('/about/:name?', function(req, res){ var name = req.params.name; res.send('<h1>' +name +'</h1>About text'); });
/* GET Blog detail page. */
routes.get('/blog/:blogid', function(req, res, next) {
// Place json data in a var.
var blogsdata = req.app.locals.blogsdata;
// Create array.
var blogItem = [];
// Check and build current URL
var currentURL = '/blog/' + req.params.blogid;
// Lop through json data and pick correct blog-item based on current URL.
blogsdata.forEach(function (item) {
if (item.title == currentURL) {
blogItem = item;
}
});
if (blogItem.length == 0) {
// Render the 404 page.
res.render('404', {
title: '404',
body: '404'
});
} else {
// Render the blog page.
res.render('blog-detail', {
blog: blogItem
});
}
});
module.exports = routes;
From the CLI error, it appears no blog data is even returned to be read into the array.
I have carefully gone through the tutorial several times and I think there are steps that may be implied that I am missing.
Can someone please help me understand how to get the blog data so that it can be read into the array and output to my template?
Also open to troubleshooting suggestions in comments.
Thanks for reading!
The error is raising in this line:
blogsdata_all.blogs.forEach(function(item){
As the error says, blogs is undefined.
If there is an error in the request or status code isn't 200, the body is not assigned to the variable, but you are not finishing the execution, so the variable in that case would be undefined.
Other possible problem is the json received doesn't have blogs as key of the body.
Check this both things and let us know if you found the problem
I have a node/express application with a controller and service. While running the unit test for controller via Grunt/Jasmine, the test runs fine but after the coverage summary I get the following error:
error: Error on SAVE state TypeError: Cannot read property 'apply' of undefined
at /node_modules/express/lib/router/index.js:603:14
at next (/node_modules/express/lib/router/index.js:246:14)
at next (/node_modules/express/lib/router/route.js:100:14)
Controller.js
var express = require('express'),
router = express.Router();
module.exports = function(app) {
app.use('/api', router);
router.post('/save', function(req, res, next) {
// Service code is invoked here with the success/error callback
// on success - res.json(response);
// on error - res.status(err.status);
});
}
ControllerSpec.js
var app = require('../mockApp'); // the app.js and the express app is mocked here
var httpMocks = require('node-mocks-http');
var request = require('request');
describe("Controller SAVE Action", function () {
it("With Error", function () {
spyOn(service, "save").andCallFake(function (req, res, headers, callback) {
callback({category: "Error"});
});
var rout = app.getRouter("/state"); // the mocked app.js contains a getRouter function which returns the corresponding router which is simply express.Router()
var request = httpMocks.createRequest({
method: 'POST',
url: '/save',
headers: {"authorization": "success"}
});
var response = httpMocks.createResponse();
rout(request, response);
var data = JSON.parse(response._getData());
expect(data.code).toEqual(400);
});
});
Mocked app.js
var m = {};
var routers = {};
module.exports = {
get: function (name) {
return m[name];
}, set: function (name, obj) {
m[name] = obj;
}, use: function (path, router) {
if (router) {
routers[path] = router;
}
}, getRouter: function (path) {
return routers[path];
}
};
Mocked Express.js
var app = require('./app'); // Mocked app.js
var services = {};
var serviceFiles = glob.sync(rootPath + '/app/services/*.js');
serviceFiles.forEach(function (file) {
var service = require(file)(app);
services[service.serviceName] = service;
});
app.set("services", services);
var controllers = glob.sync(rootPath + '/app/controllers/*.js');
controllers.forEach(function (controller) {
require(controller)(app);
});
I am working on setting up Stampery. I am unable to figure out where to set the string API key in this API.JS file. The documentation says to set the STAMPERY_TOKEN as the API key not sure how to do this. Any help would be appreciated.
The link for Stampery is https://github.com/stampery/office.
'use strict';
const express = require('express');
const router = express.Router();
const bodyParser = require('body-parser')
const Stampery = require('stampery');
const development = process.env.NODE_ENV !== 'production';
const stamperyToken = process.env.STAMPERY_TOKEN;
var proofsDict = {}
if (!stamperyToken) {
console.error('Environment variable STAMPERY_TOKEN must be set before running!');
process.exit(-1);
}
//var stampery = new Stampery(process.env.STAMPERY_TOKEN, development ? 'beta' : false);
// For now, always use production Stampery API due to not making it work against beta.
var stampery = new Stampery(process.env.STAMPERY_TOKEN);
router.use(bodyParser.json());
router.post('/stamp', function (req, res) {
var hash = req.body.hash;
// Throw error 400 if no hash
if (!hash)
return res.status(400).send({error: 'No Hash Specified'});
// Transform hash to upper case (Stampery backend preferes them this way)
hash = hash.toUpperCase()
// Throw error 422 if hash is malformed
var re = /^[A-F0-9]{64}$/;
if (!(re.test(hash)))
return res.status(422).send({error: 'Malformed Hash'});
stampery.stamp(hash, function(err, receipt) {
if (err)
res.status(503).send({error: err});
else
res.send({result: receipt.id, error: null});
});
});
router.get('/proofs/:hash', function (req, res) {
var hash = req.params.hash;
stampery.getByHash(hash, function(err, receipts) {
if (err)
res.status(503).send({error: err});
else
if (receipts.length > 0)
res.send({result: receipts[0], error: null});
else
res.status(200).send({error: 'Oops! This email has not yet been attested by any blockchain.'});
});
});
module.exports = router;
I have added the following in Azure website. Should this suffice :
You need to set up STAMPERY_TOKEN environment veriable before starting your server.
You can do this like this for example (in Windows) set STAMPERY_TOKEN=your-token&& node app.js
There are 2 ways to add this to environment (For Ubuntu).
Add to bashrc File. Like:
export STAMPERY_TOKEN="YOUR-TOKEN"
Pass these params before running server. Like:
STAMPERY_TOKEN=YOUR-TOKEN node server.js
To access this variable you can get by:
console.log(process.env["STAMPERY_TOKEN"]);
I'm testing forms-angular (http://www.forms-angular.org/).
I define a DataFormHandler variable in my index.js file. And also I need to get this variable in my controllers. How may I get it? This setter doesn't work app.set("formHandler", DataFormHandler).
Here is the code:
index.js
'use strict';
var formsAngular = require('forms-angular'); // require formsAngular
var kraken = require('kraken-js'),
app = require('express')(),
options = {
onconfig: function (config, next) {
//any config setup/overrides here
next(null, config);
}
},
port = process.env.PORT || 8000;
// Here I initialize FormHandler. It requires the app, so I initialize it here, in index.js
// HOW TO GET THIS VAR IN CONTROLLERS?
var DataFormHandler = new (formsAngular)(app);
app.set("fh", DataFormHandler); // THIS DOESN'T WORK. UNDEFINED in controller
app.use(kraken(options));
app.listen(port, function (err) {
console.log('[%s] Listening on http://localhost:%d', app.settings.env, port);
});
The setter app.set("fh", DataFormHandler) doesn't work. When I try to get fh from within a controller it is undefined:
app\controllers\index.js
'use strict';
var UserModel = require('../models/user');
module.exports = function (router) {
var user = new UserModel();
router.get('/', function (req, res) {
var DataFormHandler = req.app.get("fh");
DataFormHandler.addResource('user', UserModel);
console.log("DataFormHandler", DataFormHandler); // undefined
var model = {
hello: "Hello"
}
res.render('index', model);
});
};
How to get a variable in a controller?
I found one solution that works. But not sure that it's the correct one.
Instead of
app.set(key, value)
which doesn't work, I use
app.locals.key = value
that for some reason works.