Node.js fs.writeFile save to json keeps looping [duplicate] - node.js

I have followed many solutions provided in the previous questions but mine is not working. The problem is in .json extension. Whenever I use filename.json, the app will crash with ERR_CONNECTION_RESET but successfully created an empty .json file. However, if I change the extension to filename.txt, the fs.writeFile will successfully create the filename.txt with the data inside and the app will work as expected. Did I miss any configuration here to create the JSON file?
Here is the example code I used.
var jsonData = '{"persons":[{"name":"John","city":"New York"},{"name":"Phil","city":"Ohio"}]}';
// parse json
var jsonObj = JSON.parse(jsonData);
console.log(jsonObj);
// stringify JSON Object
var jsonContent = JSON.stringify(jsonObj);
console.log(jsonContent);
fs.writeFile("./public/output.json", jsonContent, 'utf8', function(err) {
if (err) {
console.log("An error occured while writing JSON Object to File.");
return console.log(err);
}
console.log("JSON file has been saved.");
});

So, ERR_CONNECTION_RESET means that the connection was closed midway. My guess, as in the comments, would be that it's a reloading server.
Try using --ignore public/**/*.json and it should work.

Related

Saving image in local file system using node.js

I was working on a simple code to download missing images from a site and save it in the local system, given its complete URL. I am able to get the data in binary format as response and also I am able to save it properly. But when I try to open the image it shows the format is not supported by the system. I tried to save some js and css file and they are being saved properly and I am able to view them as well. But I am having problem with all the image formats.
Here is the code I wrote:
try {
response = await axios.get(domain + pathOfFile);
console.log(response);
fs.writeFile(localBasePath + pathOfFile, response.data, "binary", (error) => {
if (error) console.log("error while writting file", error.message);
});
} catch (error) {
console.log("error in getting response", error.message);
}
domian: contains the base domain of the site
pathOfFile: contains the path of file on that domain
localBasePath: the base folder where I need to store the image
I even tried to store the response in a buffer and then tried to save the image, but still I am facing the same problem.
Any suggestions would be appreciated.
You need to define responseEncoding while calling axios.get method.
Change your line to:
response = await axios.get(domain + pathOfFile, {responseEncoding: "binary"});

How to send code written in code editor to server using POST method

I'm working on building a snippet manager app and through the interface you can create new snippets and edit them using a code editor but what I'm stuck at is how can I send the snippet code to my server using POST for it to create a new file for that snippet.
For ex. -
const getUser = async (name) => {
let response = await fetch(`https://api.github.com/users/${name}`);
let data = await response.json()
return data;
}
One solution that I can think of is to parse the code into JSON equivalent that'll contain all the tokens in JSON format but for that I'll have to add parsers for every language and select a parser based on what language the user selected. I'm trying to figure out a way to avoid having to add all the parsers unless there isnt any solution for this.
Another solution I can think of is to generate the file from the frontend and send that file through POST request.
My current stack is Node+React
Using the second solution is working for me right now. I've written the code below for it -
app.post("/create", isFileAttached, function(req, res) {
const { file } = req.files;
const saveLocation = `${saveTo}/${file.mimetype.split("/")[1]}`;
const savePath = `${saveLocation}/${file.name}`;
if (!fs.existsSync(saveLocation)) {
fs.mkdirSync(saveLocation, { recursive: true });
}
fs.writeFile(savePath, file.data.toString(), err => {
if (err) throw err;
res.status(200).send({ message: "The file has been saved!" });
});
});
With this solution I no longer have to add any parsers, since whatever's written in the files are no longer a concern anymore.

Display video from Gridfs storage in react app

I am using multer-gridfs-storage and gridfs-stream to store my video in the backend (Express/Node). When I try to retrieve the file to play on my front end (React) the player refuses to recognize the source.
I am using Video-React to display the video on download. The download is successful, I get a Binary string back from the backend, which I converted to a Blob.
try{
fileBlob = new Blob([res.data], {type : res.headers['content-type']});
}catch(err){
console.log('Error converting to blob');
console.log(err);
}
This is my Video-React player being rendered
<Player
autoPlay
ref="player"
>
<source src={this.state.fileURL} />
<ControlBar autoHide={false} />
</Player>
Then I tried two techniques
readDataAsURL
let reader = new FileReader();
reader.onload = function(event){
//rThis is just a reference to the parent function this
rThis.setState({fileURL: reader.result}, () => {
rThis.refs.player.load();
});
}
try{
reader.readAsDataURL(fileBlob);
}catch(err){
console.log('Error trying readDataURL');
console.log(err);
}
src is being set correctly but the video never loads
URL.createObjectURL
let vidURL = URL.createObjectURL(fileBlob);
rThis.setState({fileURL: vidURL}, () => {
rThis.refs.player.load();
});
src is set to a blob: url but still nothing
Is this an issue with Video-react or should I be doing something else? Any pointers to references I could look at will also help. What am I doing wrong? dataURL works in the case of images, I checked, but not video.
So after some more reading, I finally figured out the problem. Since I'm using gridfs-stream I'm actually piping the response from the server. So I was never getting the whole file, and trying to convert res.data, which is just a chunk, was a mistake. Instead, in my res object, I found the source url within the config property.
res.config.url
This contained my source url to which my server was piping the chunks. Should have figured it out earlier, considering I picked GridFS storage for precisely this reason.

How to save data from react component to a file

I want to save the content of my form from a react component to a file in the form of JSON which I want to read by another react component.
How can I achieve this.
I am trying to use node to accomplish this.
when I add the below code on the component the project compiles successfully but on the browser I am seeing the error saying that fs.writeFile is not a function.
I think this may not work and I am doing something which is not right.
Any idea?
I am using web pack.
const fs = require('fs');
const content = JSON.stringify(user);
fs.writeFile("../tmp/UserDetails.json", content, 'utf8', function (err) {
return console.log("done");
if (err) {
return console.log(err);
}
}

Error when downloading a file with Meteor from Github assets API

I'm stuck with a bug in my Meteor application. What I'm trying to do is to get a release asset file from github, and unzip it. I was able to download it from a standard browser.
The result from my Meteor request contain a Buffer, that I'm able to save to a binary if I want to, but is different from the binary I got from my browser ( I compared the hex code for each files, and even the size is different).
When I'm trying to open the archive file downloaded through Meteor (with windows zip program or with JSZip) It tells me that the file is corrupted.
Here is the code I used to download the file :
HTTP.call('GET',asset.url,{ // asset.url is a valid one
params:{
'access_token':token
},
headers: {
'Accept':"application/octet-stream",
'User-Agent':"My app",
}
},function( error, result ) {
if(error)console.log(error);
else{
console.log('file downloaded !');
var app_archive = new JSZip(); // I'm using JSZip for decompressing the stream
app_archive.load(new Buffer(result)); // fail here
package_file = app_archive.file('package.json');
console.log(package_file);
}
});
and here is the Meteor console output :
=> Meteor server restarted
I20160313-16:56:43.975(-5)? file created !
I20160313-16:56:44.105(-5)? Exception in callback of async function: Error: Corr
upted zip : can't find end of central directory
I20160313-16:56:44.106(-5)? at Object.ZipEntries.readEndOfCentral (C:\Users\
jimmy\AppData\Local\.meteor\packages\udondan_jszip\2.4.0_1\npm\node_modules\jszi
p\lib\zipEntries.js:135:19)
I20160313-16:56:44.108(-5)? at Object.ZipEntries.load (C:\Users\jimmy\AppDat
a\Local\.meteor\packages\udondan_jszip\2.4.0_1\npm\node_modules\jszip\lib\zipEnt
ries.js:197:14)
I20160313-16:56:44.114(-5)? at Object.ZipEntries (C:\Users\jimmy\AppData\Loc
al\.meteor\packages\udondan_jszip\2.4.0_1\npm\node_modules\jszip\lib\zipEntries.
js:21:14)
I20160313-16:56:44.116(-5)? at Object.module.exports [as load] (C:\Users\jim
my\AppData\Local\.meteor\packages\udondan_jszip\2.4.0_1\npm\node_modules\jszip\l
ib\load.js:11:18)
I20160313-16:56:44.117(-5)? at server/FabMo-App-Store.js:122:19
I20160313-16:56:44.119(-5)? at runWithEnvironment (packages/meteor/dynamics_
nodejs.js:110:1)
I think It may be related to an encoding issue, but I tried almost every encoding format without any success. I'm open to any suggestion.
You're right, this is an encoding issue. From the documentation, you get in the result the body of the HTTP response as a string. To get the content as string, you/the browser/the framework will need to decode it from its binary form using its encoding (UTF8 usually). You try to get a binary file, "decoding" it will corrupt it.
You need to get the result in a binary format. The issue #1670 looked promising but wasn't merged. Using meteor add http aldeed:http, I get
HTTP.call('GET',asset.url,{
params:{
responseType: "arraybuffer"
// ...
},
// ...
},function( error, result ) {
var app_archive = new JSZip();
app_archive.load(result); // result is an ArrayBuffer
});
Finally made it working by using the request package
Here is the code :
request({
method : "GET",
url : asset.url,
headers:{
'Accept':"application/octet-stream",
'User-Agent':"My App",
'token':token
},
encoding: null // <- this one is important !
}, function (error, response, body) {
if(error || response.statusCode !== 200) {
// handle error
}
var app_archive = new JSZip();
app_archive.load(body);
package_file = app_archive.file('package.json').asText();
console.log(package_file);
});

Resources