req.params undefined in module - node.js

I have an working api for serving images in a route in my server.js and want to abstract it to a separate module.
before:
app.get('/api/image/:filename', function(req, res){
var resourcePath = 'uploads/public/projectnumber/issues/small/' + req.params.filename + '.png';
console.log(resourcePath)
if(fs.existsSync(resourcePath)) {
var file = fs.readFileSync(resourcePath);
res.writeHead(200, 'Content-Type:application/pdf:image/png');
res.end(file,'binary');
}
else {
res.send(400, 'No image found');
}
})
I want something like this:
var ImageRouter = require('./routes/imageRouter');
app.use('/api/image/:filename', ImageRouter);
and I've tried writing it like this in my imageRouter.js file:
var express = require('express');
var fs = require('fs');
var router = express.Router();
router.use(function(req, res, next) {
var resourcePath = 'public/images/' + req.params.filename + '.png';
if(fs.existsSync(resourcePath)) {
var file = fs.readFileSync(resourcePath);
res.writeHead(200, 'Content-Type:application/pdf:image/png');
res.end(file,'binary');
}
else {
res.send(400, 'No image found');
}
next();
});
module.exports = router;
But req.params.filename is undefined. Where have I gone wrong?
Thanks!

You should use get() on your imageRouter.js Router and prefix it on your main app.
use() is for middlewares.
Here is imageRouter.js:
var router = require('express').Router();
var fs = require('fs');
router.get('/:filename', function(req, res) {
var resourcePath = 'public/images/' + req.params.filename + '.png';
if(fs.existsSync(resourcePath)) {
var file = fs.readFileSync(resourcePath);
res.writeHead(200, 'Content-Type:application/pdf:image/png');
res.end(file,'binary');
}
else {
res.send(400, 'No image found');
}
});
module.exports = router;
And your server.js:
var express = require('express');
var app = express();
var ImageRouter = require('./routes/imageRouter');
app.use('/api/image', ImageRouter);

Related

Sample Hello World Express App is returning binary data

The following doesnt seem to work. It's simple Express sample code. You can ignore the other responses. Im just trying to get the basic '/' home page working and that's refusing to work. Code is as follows:
var express = require('express');
var sR = require('./routes/index');
var path = require('path');
var urlencoded = require('url');
var bodyParser = require('body-parser');
var json = require('json');
var methodOverride = require('method-override');
var jade = require('jade');
var fs = require('fs');
var http = require('http2');
const cookieParser = require('cookie-parser');
const logger = require('morgan');
const MongoClient = require('mongodb').MongoClient;
const assert = require('assert');
const dbLoc = 'mongodb://localhost:27017';
const dbName = 'gothamDB';
var dbConn = null;
const dbURL = "mongodb://gotthamUser:abcd1234#localhost:27017/gothamDB"
const mongoClient = new MongoClient(dbURL, { useNewUrlParser: true, useUnifiedTopology: true});
// Use connect method to connect to the server
dbConn = mongoClient.connect(function(err, client) {
assert.strictEqual(null, err);
console.log("Connected successfully to server");
dbConn = client;
});
var app = express();
app.set('port', 8080);
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.set('/', function(req, res){
res.send("Hello World");
res.end();
console.log("Hello World sent");
});
app.post('/create_collection', function(req, res){
var db = dbConn.db('gothamDB');
var userData = db.createCollection(req.body.coll_name, function(err){
if(err){
res.send('Error creating database: ' + req.body.coll_name);
return;
}
res.send('Database ' + req.body.dbname + ' created successfully');
});
});
app.post('/new_contact', function(req, res){
var name = req.body.name;
var phone = req.body.phone;
var db = dbConn.db('gothamDB');
var coll = db.collection(req.body.coll_name);
collection.insert(
{name : name, phone: phone}
, function(err, result) {
assert.strictEqual(err, null);
assert.strictEqual(1, result.result.n);
assert.strictEqual(1, result.ops.length);
res.send("Inserted new record into the collection");
});
});
app.post('view_contact', function(req, res){
var db = dbConn.db('gothamDB');
var coll = db.collection(req.body.coll_name);
coll.find({'phone' : req.body.phone}).toArray(function(err, docs){
if(err) {
res.send("Error looking up the data");
return;
}
res.send(docs);
return;
});
});
app.post('delete_contact', function(req, res){
var db = dbConn.db('gothamDB');
var coll = db.collection(req.body.coll_name);
coll.deleteOne({'phone' : req.body.phone}).toArray(function(err, docs){
if(err) {
res.send("Error looking up the data");
return;
}
res.send(docs);
return;
});
});
//const key = path.join(__dirname + '/security/server.key');
//const cert = path.join(__dirname + '/security/server.crt');
const options = {
key: fs.readFileSync(__dirname + '/security/server.key'),
cert: fs.readFileSync(__dirname + '/security/server.crt')
}
http.createServer(app).listen(app.get('port'), function(err){
console.log('Express server lisetning on port ' + app.get('port'));
})
console.log("Server started");
Any clue? Browser shows as follows:
Itt's showing an ERR_INVALID_HTTP_RESPONSE
if I run a curl command, it shows the following:
NodeExample % curl -X GET 'http://localhost:8080/'
Warning: Binary output can mess up your terminal. Use "--output -" to tell
Warning: curl to output it to your terminal anyway, or consider "--output
Warning: <FILE>" to save to a file
If I put a breakpoint at the line:
res.send("Hello World");
that never hits. I've also tried putting in
res.header("Content-Type", "application/json");
but since the breakpoint never hits, it is not going to help I guess.
You are using set here
app.set('/', function(req, res){
res.send("Hello World");
res.end();
console.log("Hello World sent");
});
It should be get
app.get('/', function(req, res){
res.send("Hello World");
res.end();
console.log("Hello World sent");
});

Do variables reset to their initial values after every post method in Node.js?

//jshint esversion:6
var logger;
var logName;
var pollName;
var names = [];
const fs = require("fs");
const express = require("express");
const bodyParser = require("body-parser");
const readline = require('readline');
const fileName1 = __dirname + "/public/logger.json";
const fileName2 = __dirname + "/public/poll.json";
const dataWriter1 = require(fileName1);
const dataWriter2 = require(fileName2);
const app = express();
app.use(bodyParser.urlencoded({
extended: true
}));
var reader = readline.createInterface({
input: fs.createReadStream(__dirname + '/public/names.txt'),
console: false
});
reader.on('line', function(line) {
names.push(line);
});
app.use(express.static(__dirname + '/public'));
app.get("/", function(req, res) {
res.sendFile(__dirname + "/index.html");
});
app.get("/route", function(req, res)
{
fs.readFile(fileName1,'utf-8',(err,data)=>
{
res.set('Content-Type', 'application/json');
res.send(data);
});
});
app.post("/", function(req, res)
{
if(req.body.button==1)
{
logName = req.body.name;
console.log(logName);
for (i = 0; i < names.length; i++)
{
if (logName == names[i])
{
logger=true;
break;
}
}
if(logger!=true)
{
logger=false;
}
dataWriter1.logger = logger;
fs.writeFile(fileName1, JSON.stringify(dataWriter1), function writeJSON(err)
{
if (err) return console.log(err);
console.log(JSON.stringify(dataWriter1));
});
logger=false;
}
else if(req.body.button==2)
{
console.log(logName);
pollName=req.body.option;
for(i=0;i<dataWriter2.list.length;i++)
{
if(dataWriter2.list[i].name==pollName)
{
dataWriter2.list[i].votes++;
dataWriter2.list[i].voter_name.push(logName);
//logName is undefined
}
}
fs.writeFile(fileName2, JSON.stringify(dataWriter2), function writeJSON(err)
{
if (err) return console.log(err);
console.log(JSON.stringify(dataWriter2));
});
}
res.redirect("/");
});
app.listen(3000, function()
{
console.log("Server Started!");
});
This is my server code in node.js. I have 2 forms in index.html and both have submit buttons with different value to differentiate. The first form has to be submitted to view the second form. My problem is that even though I'm storing a data from the first form in a variable it resets when I submit the second form even though when the server is still running.
I cannot understand why logName becomes undefined while I'm posting with the second submit button and is there any workaround?
I figured it out.. The server was restarting due to changes in a JSON file as I was running it by nodemon. Added JSON file to ignore list and now it's all fine.

MEAN API using node-restful no response

I'm trying to setup API for multiple projects that use same database structure (running on same CMS) but when I'm trying to reach some data I get no response.
index.js
var express = require("express");
var cors = require("cors");
var mongoose = require("mongoose");
var bodyParser = require("body-parser");
var methodOverride = require("method-override");
var _ = require("lodash");
var passport = require("passport");
var dbconfig = require("./app/config/database");
// Create the application
var app = express();
var user = require("./app/routes/User");
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(methodOverride('X-HTTP-Method-Override'));
var connections = [];
// Auto CORS
app.use(cors());
/* Mnual CORS Start
app.use(function(req, res, next){
res.header("Access-Controll-Allow-Origin", "*");
res.header("Access-Controll-Allow-Methods", "GET,PUT,POST,DELETE");
res.header("Access-Controll-Allow-Headers", "Content-Type");
next();
});
/* Manual Cords end */
// Passport Middleware
app.use(passport.initialize());
app.use(passport.session());
require("./app/config/passport")(passport);
app.get("/", (req, res) => {
res.json({ msg: "Nothing here mate" });
});
//------------ THIS IS WORKING ----------------
app.get("/db/:database/navigation", (req, res) => {
var dbname = req.params.database;
var conn = connections[dbname];
var navs = conn.model("navigation", app.models[dbname].navigation);
// Send json data/error
if (navs) navs.find({}, (err, data) => res.json(data));
else res.json({ error: true, msg: "Model not found" });
});
// -------------------------------------------------------
// Setup databases for all projects
_.each(dbconfig.databases, db => {
var appModels = require("./app/models/index");
var processed = 0;
// We will use prefix for all routes /db/:database/
var routePrefix = "/db/" + db.name;
// Use user section
app.use(routePrefix + "/user", user);
// Connection callback - we need to wait for modules to initialize
var connect = () => {
// Initialize connection
connections[db.name] = new mongoose.Mongoose().createConnection(db.url);
// Create some callbacks
connections[db.name].on("connected", () => { console.log("Connected to database " + db.url); });
connections[db.name].on("error", onDatabaseError)
// Once we initialize connection, we need to setup all routes
connections[db.name].once("open", function () {
// Load routes
var routes = require('./app/routes');
// Loop trough routes and use all of them
_.each(routes, function (controller, route) {
var newRoute = routePrefix + route;
app.use(newRoute, controller(app, newRoute, db.name));
});
});
};
// Initialize models
_.each(appModels, (model, index) => {
// Create object if doenst exist
if (app.models == null)
app.models = {};
if (app.models[db.name] == null) {
app.models[db.name] = { [model.name]: model.model };
}
else {
app.models[db.name] = Object.assign(app.models[db.name], { [model.name]: model.model });
}
processed++;
// if this was the last process we are ready to connect
if (processed === appModels.length)
connect();
});
});
app.listen(3000);
app/models/index.js
module.exports = [
{
name: "navigation",
model: require('./Navigation.js')
},
...
];
app/routes.js
module.exports = {
'/navigation': require('./controllers/NavigationController'),
....
};
app/controllers/NavigationController.js
var restful = require("node-restful");
module.exports = function(app, route, dbname){
console.log(route);
var rest = restful.model(
"navigation",
app.models[dbname].navigation
).methods(['get', 'put', 'post', 'delete']);
rest.register(app, route);
// Return middleware
return function(req, res, next){
next();
};
};
Navigation.js is basically just a schema. If I set up route manually like this:
app.get("/db/:database/navigation", (req, res) => {
var dbname = req.params.database;
var conn = connections[dbname];
var navs = conn.model("navigation", app.models[dbname].navigation);
// Send json data/error
if (navs) navs.find({}, (err, data) => res.json(data));
else res.json({ error: true, msg: "Model not found" });
});
it works just fine. I guess I need to assign connection somewhere to restful but I have no idea where. If I use single connection with mongoose.connect() everything works perfectly, but that's not what I need :)
Does anyone have any idea what to do next to get this to work? Will appreciate any help, thanks.
Kind of dug into it and made an extension to change driver reference
Here are all the changes, hope it helps someone in future :)
extensions/restful/index.js
var restful = require("node-restful"),
model = require("./model"),
mongoose = require('mongoose');
exports = module.exports = restful;
exports.model = model;
exports.mongoose = mongoose;
extensions/restful/model.js
exports = module.exports = model;
exports.changeDriver = function(driver){
mongoose = driver;
}
// original model function from node-restful/lib/model.js
function model() {
var result = mongoose.model.apply(mongoose, arguments),
default_properties = defaults();
if (1 === arguments.length) return result;
for (var key in default_properties) {
result[key] = default_properties[key];
}
return result;
}
app/controllers/navigation.js
var restful = require("../extensions/restful");
module.exports = function(app, route, db)
{
restful.model.changeDriver(db.mongoose);
// Setup controller REST
var rest = restful.model(
"navigation",
app.models[db.name].navigation
).methods(['get', 'put', 'post', 'delete']);
// Register this endpoint with the application
rest.register(app, route);
// Return middleware
return function(req, res, next){
next();
};
};
index.js
....
var connect = () => {
// Initialize connection
var $db = databases[_db.name] = {
mongoose: new mongoose.Mongoose(),
name: _db.name
};
$db.mongoose.connect(_db.url);
// Create some callbacks
$db.mongoose.connection.on("connected", () => { console.log("Connected to database " + _db.url); });
$db.mongoose.connection.on("error", (err) => { console.log("Database error: " + err); });
// Once we initialize connection, we need to setup all routes
$db.mongoose.connection.once("open", function () {
// Custom routes for user section
var userRoutes = new UserRoutes($db.mongoose);
app.use(routePrefix + "/user", userRoutes.getRouter());
// Load routes
var routes = require('./app/routes');
// Loop trough routes and use all of them
_.each(routes, function (controller, route) {
var newRoute = routePrefix + route;
app.use(newRoute, controller(app, newRoute, $db));
});
});
};
....

How to upload and download a file in a single service call in nodejs?

I can upload a file via postman and download a file from server in two different service .. But what i need is ..In a single call i should able to upload the file to server ,then perform some operation after performing some operation i should able to download the file automatically.
Here is my code.
My firsts service(file upload operation)
var express = require('express');
var fs = require('fs');
var formidable = require('formidable');
var router = express.Router();
/* GET home page. */
router.post('/', function(req, res, next) {
var form = new formidable.IncomingForm();
form.uploadDir="./file"
form.keepExtensions=true;
form.maxFileSize=10*1024*1024;
form.multiples=false;
form.parse(req, function (err, fields, files) {
res.write('File uploaded');
res.end();
});
});
module.exports = router;
Download service
var express = require('express');
var router = express.Router();
var express = require('express');
router.get('/', function(req, res, next) {
var file = './file/myOutput.txt';
var name = 'ENC.txt'
res.download(file, name);
});
module.exports = router;
Now i need to make this two service as one?
var express = require('express');
var formidable = require('formidable');
var app=express();
async function calculation(parameters)
{
if(parameters)
{
//Here you can do calculation depending upon parameter values
}
else
{
//Display error or as per your choice
}
}
app.get('/',function(req,res){
res.sendFile(__dirname+'/index.html');
});
async function cal(res,file,form)
{
try{
const data = await calculation(true)
if(data){
res.set({
'Location' : __dirname+'/index.html',
});
res.download( __dirname+file.name);
}
}
catch(error)
{
console.log(error);
}
}
app.post('/',function (req,res){
var form = new formidable.IncomingForm();
form.parse(req);
form.on('fileBegin',function(name,file){
file.path = __dirname+file.name;
console.log("Uploading");
});
form.on('file',
function(name,file)
{
console.log('Uploaded ',file.name);
cal(res,file);
});
});
Hope it helps

callback not fetching record in nodejs

i want to pass email in postman and want to print the fetched json data to console. but it is not fetching any data. so help me to solve this issue
mongoconnect.js
var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/";
var dbo=null;
exports.connection=function(){
if(dbo!=null) return
MongoClient.connect(url, function(err, db) {
if (err) throw err;
dbo = db.db("hospital_api");
});
}
var get = function (){
return dbo;
}
exports.email=function(r){
get().dbo.collection("doctor").find({"email":r}).toArray(function(err,result)
{
if(err) throw err;
console.log(result)
return result;
})
}
doctor.js
var express = require('express');
var router = express.Router();
var bodyParser = require("body-parser");
var validator = require('validator');
var mongo= require('./mongoconnect')
var app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
router.post('/',function(req,res)
{
d=mongo.email(req.body.email)
console.log(d);
})
module.exports = router;
In export.email, you have a typo
exports.email = function(r) {
get().collection("doctor").find({"email":r}) // no ".dbo" after get()

Resources