Node how to pass file to http.write method? - javascript

I woudl like to print file to res.write() method but I get error:
TypeError: First argument must be a string or Buffer
My code:
var fs = require("fs");
var http = require("http");
http.createServer(function (req, res){
res.write(getData());
res.end();
}).listen(3333);
function getData(){
fs.readFile('testfs.txt', function(err, data){
if(err)
{
console.log("Error: " + err);
}else {
console.log(data.toString());
return data.toString();
}
});
}
What's the problem?

res.write didn't get string nor buffer because your function getData wasn't asynchronous. Here's the fix I hope will solve your problem:
http.createServer(function (req, res){
getData(function(data){
res.write(data);
res.end();
}));
}).listen(3333);
function getData(cb){
fs.readFile('testfs.txt', function(err, data){
if(err)
{
console.log("Error: " + err);
}else {
cb(data.toString());
}
});
}
Where cb argument is a callback function obviously.

Alternatively, you can use streams:
const http = require('http');
const fs = require('fs');
http.createServer((req, res) => {
fs.createReadStream('testfs.txt')
.on('error', (e) => {
console.log('Error:', e);
res.statusCode = 500;
res.end();
})
.pipe(res)
}).listen(3333);

Do it the other way around; just call getData and pass in response, then when the file is loaded, call response.end(string).

Related

Return the result of execFile in node.js

I want to get the result back from a execFile call:
var http = require('http');
var fs = require('fs');
const execFile = require('child_process').execFile;
http.createServer(function (req, res) {
fs.readFile('index.html', function(err, data) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.write(execute());
return res.end();
});
}).listen(8080);
var execute = function(){
console.log("start execution");
let result = execFile('./demo-files/demo.sh', ['1st', '2nd', '3rd'], function(err, data){
if(err){
console.log("ERROR:\n" + err);
}
return data.toString();
});
return result;
}
But I'm not sure which way is the right syntax.
Surprisingly, I can't seem to find the exact post on SO with my question? If duplicate, I will happily consider the other source.

remove image file from backend with node File System and MongoDB

I need to remove an image file from my backend, the folder is: /uploads. When i call the function deleteProduct it removes the product from the data base but the image of the product its still in folder.
deleteProduct: (req, res) => {
let productId = req.params.id;
Product.findById(productId, (err, res) =>{
var imageResponse = res.image;
console.log(imageResponse);
});
//console.log(imageResponse);
//fs.unlink('./uploads' + imageResponse );
When i try to access imageResponse outside the findById, console prints: "imageResponse" is not defined. Then i need to delete that file with fs. Im not sure if i wrote correct the unlink function. Thanks in advance.
For fs.unlink
Have you made sure to:
Include fs = require('fs')?
Used __dirname?
Include file extension (.png, .jpg, .jpeg)?
const fs = require('fs');
fs.unlink(__dirname + '/uploads' + imageResponse + ".png", (err) => {
if (err) throw err;
console.log('successfully deleted file');
});
For image response being undefined
You didn't provide information on the Product constructor, but I assume Product.findById is asynchronous. You may need to use an async function
const fs = require('fs');
async function deleteProduct (req, res) => {
let productId = req.params.id;
Product.findById(productId, (err, res) =>{
var imageResponse = res.image;
console.log(imageResponse);
fs.unlink(__dirname + '/uploads' + imageResponse + ".png", (err) => {
if (err) throw err;
console.log('successfully deleted file');
});
});
}
Further reading:
Node File API: https://nodejs.org/api/fs.html
Async functions: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function
Finally it seems to be working, the file succesfully vanished from the folder, im still open for advices, thanks.
deleteProduct: (req, res) => {
let productId = req.params.id;
Product.findById(productId, (err, res) =>{
if(err) return res.status(500).send({message: 'Error'});
fs.unlink('./uploads/' + res.image, (err) => {
if(err) return res.status(500).send({message: 'Error'});
})
});

GET images from GridFs to Angular

I´m storing images from my angular app in MongoDB using GridFs. But i cant figure out, how to GET the images out of the DB to the app?
I´m using a custom objectId for the query.
EDIT
It looks like the GET part now works, but then there was no media in the collection. I played a bit with the code, and now I can see fs.chunks and fs.files in the database. I think the problem is, that I try to query for metadata in the GET request. This returns no response data. Anybody got an idea how to fix this?
var fs = require('fs');
var conn = mongoose.connection;
var Grid = require ('gridfs-stream');
Grid.mongo = mongoose.mongo;
var gfs = Grid (conn.db);
var buffer = "";
app.post('/uploads/', multer({
upload: null,
onFileUploadStart: function (file, req){
this.upload = gfs.createWriteStream({
filename: file.originalname,
metadata:{"objectId" : req.body.project_id},
mode: "w",
chunkSize: 1024*4,
content_type: file.mimetype,
root: "fs",
});
},
onFileUploadData: function(file, data) {
this.upload.write(data);
},
onFileUploadComplete: function(file, res) {
done=true;
}
}), function(req, res){
res.status(200);
res.send("Success!");
});
app.route('/uploads/media/:projectId').get(function (req, res){
var readstream = gfs.createReadStream({
"metadata.objectId" : req.params.projectId
});
res.set('Content-Type', 'image/jpeg');
readstream.pipe(res);
});
You need to write the stream back out to your response. Here is another similar question. But basically you either need to pipe the stream to your response, or use the stream's end event and write the result to your response. The following code pipes to the response and sets a content-type of image/jpeg.
app.get('/uploads/:objectId', function(req, res){
var options = {
_id : req.params.objectId
};
gfs.exist(options, function(err, exists) {
if(!exists) {
res.status(404);
res.end();
} else {
var readstream = gfs.createReadStream(options);
res.set('Content-Type', 'image/jpeg');
readstream.pipe(res);
}
});
});
var pi_id = fields.pic_id;
gfs.findOne({ _id: pi_id }, function (err, file) {
console.log(file);
if (err) return res.status(400).send(err);
if (!file) return res.status(404).send('');
res.set('Content-Type', file.contentType);
res.set('Content-Disposition', 'attachment; filename="' + file.filename + '"');
var readstream = gfs.createReadStream({
_id: file._id
});
readstream.on("error", function(err) {
console.log("Got error while processing stream " + err.message);
res.end();
});
readstream.pipe(res);
console.log(readstream.pipe(res))
});

Node js displaying images from server

I am trying to display an image on a basic web page on a localhost w/ port 5000
here is main.js
var http = require('http');
var domain = require('domain');
var root = require('./root');
var image = require('./image');
function replyError(res) {
try {
res.writeHead(500);
res.end('Server error.');
} catch (err) {
console.error('Error sending response with code 500.');
}
};
function replyNotFound(res) {
res.writeHead(404);
res.end('not found');
}
function handleRequest(req, res) {
console.log('Handling request for ' + req.url);
if (req.url === '/') {
root.handle(req, res);
} else if (req.url === '/image.png'){
image.handle(req, res);
} else {
replyNotFound(res);
}
}
var server = http.createServer();
server.on('request', function(req, res) {
var d = domain.create();
d.on('error', function(err) {
console.error(req.url, err.message);
replyError(res);
});
d.run(function() { handleRequest(req, res); });
});
function CallbackToInit(){
server.listen(5000);
};
root.init(CallbackToInit);
Using callbacks I want the server to start listening(5000) only after the init function of the following code runs
var http = require('http');
var body;
exports.handle = function(req, res) {
res.writeHead(200, {
'Content-Type': 'image/png'
});
res.end(body);
};
exports.init = function(cb) {
require('fs').readFile('image.png', function(err, data) {
if (err) throw err;
body = data;
cb();
});
}
It's an assignment I can't use express
I am trying to get image.png to be displayed, I think body = data doesn't work because it can't hold an image like a string? I don't want to put any HTML into my js file.
Don't roll your own app server. Use one of the great web app frameworks like express or connect.
var express = require('express');
var app = express();
app.use(express.logger());
app.use(express.static(__dirname + '/public'));
app.listen(process.env.PORT || 5000);
Trust me, this is better.
Take a look at the node.js example for a simple http server or a tutorial/example, such as this, for serving static files through a simple server.

Cannot call method 'send' of undefined(response is undefined) in express js

I have tried to pass a variable from my index.html to the database(maildata.js) through app.js(server) and get the corresponding data
I am able to get the data from the database but couldnt send that back to the server(app.js)
app.js
var express = require('express');
var maildata= require('./maildata');
var app = express();
app.configure(function(){
app.use(express.bodyParser());
});
app.get('/', function(request, response){
response.sendfile(__dirname + '/mailbox.html');
});
app.post('/mailboxpost',function(request, response) {
var input=request.query.search;
var result=maildata.getMailData(input);
response.send(result);
response.end();
});
app.listen(8888);
console.log('Server is running on port 8888');
maildata.js
exports.getMailData=function(data,response) {
var stop_name= data;
connection.query("select stop_name,stop_comment from stoplist where stop_name= '"+stop_name+"' limit 1",function(err, rows) {
if (err) {
console.log('error in fetching ' + err);
}
else{
var jsonString1= JSON.stringify(rows);
connection.query("select mailbox_sequence_no from stoplist where stop_name= '"+stop_name+"'",function(err, rows) {
if (err) {
console.log('error in fetching ' + err);
}
else{
var jsonString2 = JSON.stringify(rows);
connection.query("select party_head from stoplist where stop_name= '"+stop_name+"'", function(err, rows) {
if (err) {
console.log('error in fetching ' + err);
}
else{
var jsonString3 = JSON.stringify(rows);
var result=jsonString1+'/'+jsonString2+'/'+jsonString3;
response.send(result);
}
});
}
});
}
});
}
Thanks in Advance
How about sending response along when you call the function?
var result=maildata.getMailData(input); // something missing here
Your getMailData function expects two arguments:
exports.getMailData=function(data,response) { ... }
but you give it only one:
var result=maildata.getMailData(input);
Which makes the value of the response argument undefined.
Here is what you should do:
app.post('/mailboxpost',function(request, response) {
var input=request.query.search;
maildata.getMailData(input, response);
});
and let maildata.getMailData handle the response sending, as you did in response.send(result);
I have used asynchronous callback method in my app.js.
I got the result
var result=maildata.getMailData(input,response,function(data){
response.send(data);
response.end();
});
Thanks all

Categories