Node: How to read file? - javascript

I want to read a file and return is as a response to GET request
This is what I am doing
app.get('/', function (request, response) {
fs.readFileSync('./index.html', 'utf8', function (err, data) {
if (err) {
return 'some issue on reading file';
}
var buffer = new Buffer(data, 'utf8');
console.log(buffer.toString());
response.send(buffer.toString());
});
});
index.html is
hello world!
When I load page localhost:5000, the page spins and nothing happens, what is I am doing incorrect here
I am newbie to Node.

You're using the synchronous version of the readFile method. If that's what you intended, don't pass it a callback. It returns a string (if you pass an encoding):
app.get('/', function (request, response) {
response.send(fs.readFileSync('./index.html', 'utf8'));
});
Alternatively (and generally more appropriately) you can use the asynchronous method (and get rid of the encoding, since you appear to be expecting a Buffer):
app.get('/', function (request, response) {
fs.readFile('./index.html', { encoding: 'utf8' }, function (err, data) {
// In here, `data` is a string containing the contents of the file
});
});

Related

How do I write the result from res.json to a proper json file using node.js? [duplicate]

This question already has answers here:
Writing to files in Node.js
(18 answers)
Closed 5 years ago.
This is the code snippet. The query returns in json form but how do I write these values in a JSON file?
app.get('/users', function(req, res) {
User.find({}, function(err, docs) {
res.json(docs);
console.error(err);
})
});
If you're going to be writing to a file within a route callback handler you should use the Asynchronous writeFile() function or the fs.createWriteStream() function which are a part of the fs Module in the Node.js Core API . If not, your server will be unresponsive to any subsequent requests because the Node.js thread will be blocking while it is writing to the file system.
Here is an example usage of writeFile within your route callback handler. This code will overwrite the ./docs.json file every time the route is called.
const fs = require('fs')
const filepath = './docs.json'
app.get('/users', (req, res) => {
Users.find({}, (err, docs) => {
if (err)
return res.sendStatus(500)
fs.writeFile(filepath, JSON.stringify(docs, null, 2), err => {
if (err)
return res.sendStatus(500)
return res.json(docs)
})
})
})
Here is an example usage of writing your JSON to a file with Streams. fs.createReadStream() is used to create a readable stream of the stringified docs object. Then that Readable is written to the filepath with a Writable stream that has the Readable data piped into it.
const fs = require('fs')
app.get('/users', (req, res) => {
Users.find({}, (err, docs) => {
if (err)
return res.sendStatus(500)
let reader = fs.createReadStream(JSON.stringify(docs, null, 2))
let writer = fs.createWriteStream(filename)
reader.on('error', err => {
// an error occurred while reading
writer.end() // explicitly close writer
return res.sendStatus(500)
})
write.on('error', err => {
// an error occurred writing
return res.sendStatus(500)
})
write.on('close', () => {
// writer is done writing the file contents, respond to requester
return res.json(docs)
})
// pipe the data from reader to writer
reader.pipe(writer)
})
})
Use node's file system library 'fs'.
const fs = require('fs');
const jsonData = { "Hello": "World" };
fs.writeFileSync('output.json', JSON.strigify(jsonData));
Docs: fs.writeFileSync(file, data[, options])

Get request doesn't work server side

I am making basic web server using nodejs and express module. It has to be able to respond to POST and GET requests. POST is just working fine, but GETdoesn't return anything. In console there's a textStatus of an error parserror and SyntaxError: Unexpected end of input at Object.parse (native) at jQuery.parseJSON error. I'm new to NodeJS and Express, please tell me where I went wrong.
var express = require('express'),
server = express(),
fs = require('fs');
server.use(express.static('../client'));
server.post('/students.json', function (req, res) {
var bodyStr = '';
req.on('data', function (chunk) {
bodyStr += chunk.toString();
});
req.on('end', function () {
fs.readFile('students.json', function (err, data) {
var encodedObj = data.toString('utf8'), //encoding what's inside of .json into human symbols
parsedObj = JSON.parse(encodedObj);
parsedObj.push(JSON.parse(bodyStr)); //adding newly created parsed obj into array
fs.writeFile('students.json', JSON.stringify(parsedObj), function (err) { //rewriting file with new array
if (err) {
console.log(err);
}
});
});
});
});
server.get('/students.json', function (req, res) {//what's wrong???
res.send();
});
var server = server.listen(8888);
What are you trying to res.send()? It looks empty to me. Try:
res.send('Hello World!'); // A string
...or...
res.send([{'name': 'Joe Student'},{'name': 'Sally Goestoskuhl'}]); // Array
...or...
res.send({}); // Empty json response
...or...
res.send(404); // Any integer is considered an HTTP error code
...or...
res.setHeader('Content-Type', 'application/json');
res.send(JSON.stringify({ variable: 'value' }));
...or...
// Assuming your json is in the public folder...
res.sendFile(path.join(__dirname, '../public', 'students.json'));
res.send(); on it's own just sends an empty response.
If you then try to json_decode it, you'll get an error.
If I interpret your question correctly, you want both POST and GET to return the same result?
You could do this pretty simply like this:
function sendJSON(req, res)
{
//JSON code from your existing server.post
}
app.get('/students.json', sendJSON);
app.post('/students.json', sendJSON);

Piping images versus sending callback body in node.js with request

I'm using node.js 0.10.33 and request 2.51.0.
In the example below, I've built a simple web server that proxies image using request. There are two routes set up to proxy the same image..
/pipe simply pipes the raw request to the response
/callback waits for the request callback and send the response headers and the body to the response.
The pipe example works as expected but the callback route won't render the image. The headers and the body appear to be the same.
What about the callback route is causing the image to break?
Here is the example code:
var http = require('http');
var request = require('request');
var imgUrl = 'https://developer.salesforce.com/forums/profilephoto/729F00000005O41/T';
var server = http.createServer(function(req, res) {
if(req.url === '/pipe') {
// normal pipe works
request.get(imgUrl).pipe(res);
} else if(req.url === '/callback') {
// callback example doesn't
request.get(imgUrl, function(err, resp, body) {
if(err) {
throw(err);
} else {
res.writeHead(200, resp.headers);
res.end(body);
}
});
} else {
res.writeHead(200, {
'Content-Type': 'text/html'
});
res.write('<html><head></head><body>');
// test the piped image
res.write('<div><h2>Piped</h2><img src="/pipe" /></div>');
// test the image from the callback
res.write('<div><h2>Callback</h2><img src="/callback" /></div>');
res.write('</body></html>');
res.end();
}
});
server.listen(3000);
Result in this
The problem is that body is a (UTF-8) string by default. If you're expecting binary data, you should explicitly set encoding: null in your request() options. Doing so will make body a Buffer, with the binary data intact:
request.get(imgUrl, { encoding: null }, function(err, resp, body) {
if(err) {
throw(err);
} else {
res.writeHead(200, resp.headers);
res.end(body);
}
});

Download image from url using request and save to variable

Is there someway I can download an image from request and save it to a variable?
request.head(url, function(err, res, body){
request(url).pipe(fs.createWriteStream(image_path));
});
right now I'm piping the result to a write stream. But instead I would like to save it to a variable so I can use it in my program. Is there any way to do this?
As what you request is an image, so you can get the response as Buffer .
var request = require('request'), fs = require('fs');
request({
url : 'http://www.google.com/images/srpr/logo11w.png',
//make the returned body a Buffer
encoding : null
}, function(error, response, body) {
//will be true, body is Buffer( http://nodejs.org/api/buffer.html )
console.log(body instanceof Buffer);
//do what you want with body
//like writing the buffer to a file
fs.writeFile('test.png', body, {
encoding : null
}, function(err) {
if (err)
throw err;
console.log('It\'s saved!');
});
});

How do I compile jade on request rather than just server start?

I'm looking to compile my jade on server request/response that way I can make changes to the jade file and see it in real time, rather than having to restart the server every time. This is the fake mockup I have so far.
var http = require('http')
, jade = require('jade')
, path = __dirname + '/index.jade'
, str = require('fs').readFileSync(path, 'utf8');
function onRequest(req, res) {
req({
var fn = jade.compile(str, { filename: path, pretty: true});
});
res.writeHead(200, {
"Content-Type": "text/html"
});
res.write(fn());
res.end();
}
http.createServer(onRequest).listen(4000);
console.log('Server started.');
I hope I made myself clear!
You're only reading the file once, on server startup. If you wanted to have it read changes you'd have to read it on request, meaning your mock-up would look more like:
function onRequest(req, res) {
res.writeHead(200, {
"Content-Type": "text/html"
});
fs.readFile(path, 'utf8', function (err, str) {
var fn = jade.compile(str, { filename: path, pretty: true});
res.write(fn());
res.end();
});
}
Something like that would read the file every time, which is probably okay for development purposes, but if you only wanted to reload/process the file when something changed, you might use a file watcher (fs.watch might fit this bill).
Something like this (just an untested example as an idea):
var fn;
// Clear the fn when the file is changed
// (I don't have much experience with `watch`, so you might want to
// respond differently depending on the event triggered)
fs.watch(path, function (event) {
fn = null;
});
function onRequest(req, res) {
res.writeHead(200, {
"Content-Type": "text/html"
});
var end = function (tmpl) {
res.write(tmpl());
res.end();
};
if (fn) return end(fn);
fs.readFile(path, 'utf8', function (err, str) {
fn = jade.compile(str, { filename: path, pretty: true});
end(fn);
});
}

Categories