How to save data from react component to a file - node.js

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);
}
}

Related

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

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.

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.

File input meteor cfs

So i see this code on the Docs
Template.myForm.events({
'change .myFileInput': function(event, template) {
FS.Utility.eachFile(event, function(file) {
Images.insert(file, function (err, fileObj) {
//Inserted new doc with ID fileObj._id, and kicked off the data upload using HTTP
});
});
}
});
But i dont want the file upload inmediatly when i click "myFileInptu" , i want to store that value (from the input), and insert lately with a button, so there is some way to do this?
Also its there a way to upload a FSCollection without a file? just metadata
Sorry for bad english hope you can help me
Achieving what you want to requires a trivial change of the event, i.e switching from change .myFileInput to submit .myForm. In the submit event, you can get the value of the file by selecting the file input, and then storing it as a FS File manually. Something like:
'submit .myForm': function (event, template) {
event.preventDefault();
var file = template.find('#input').files[0];
file = new FS.File(file);
// set metadata
file.metadata = { 'caption': 'wow' };
Images.insert(file, function (error, file) {
if (!error)
// do something with file._id
});
}
If you're using autoform with CollectionFS, you can put that code inside the onSubmit hook. The loop you provided in your question works also.
As for your second question, I don't think FS.Files can be created without a size, so my guess is no, you can't just store metadata without attaching it to a file. Anyways, it seems to me kind of counterintuitive to store just metadata when the metadata is supposed to describe the associated image. You would be better off using a separate collection for that.
Hope that helped :)

Advice: flatiron, formidable and aws s3

I'm new with serverside programming with node.js. I'm sticking together a tiny webapp with it right now and having the usual startup learning to do. The following piece of code WORKS. But I would love to know if it's more or less a right way to do a simple file upload from a form and throw it into aws s3:
app.router.post('/form', { stream: true }, function () {
var req = this.req,
res = this.res,
form = new formidable.IncomingForm();
form
.parse(req, function(err, fields, files) {
console.log('Parsed file upload' + err);
if (err) {
res.end('error: Upload failed: ' + err);
} else {
var img = fs.readFileSync(files.image.path);
var data = {
Bucket: 'le-bucket',
Key: files.image.name,
Body: img
};
s3.client.putObject(data, function() {
console.log("Successfully uploaded data to myBucket/myKey");
});
res.end('success: Uploaded file(s)');
}
});
});
Note: I had to turn buffer off in union / flatiron.plugins.http.
What I would like to learn is, when to stream load a file and when to syncload it. It will be a really tiny webapp with little traffic.
If it's more or less good then please consider this as a token of working code which I also would throw into a gist. It's not that easy to find documenation and working examples of this kind of stuff. I like flatiron alot. But it's small module approach leads to lots of splattered docs and examples all over the net, speak alone of tutorials.
You should use other module than formidable because as far as I know formidable does not have s3 storage option , then you must save the files in your server before uploading it.
I would recommend you to use : multiparty
Use this example in order to upload directly to S3 without saving it locally in your server.

Sending text to the browser

I have managed to get file uploading work in Node.js with Express, and in the code i'm checking whether it's an image or not that the user is trying to upload.
If the file was successfully uploaded I want to show a message to the user, directly to the HTML page with the uploading form. The same should be if the file the user tried to upload wasn't an image, or something else happened during the upload.
The code below works (res.send...) but it opens up a new page containing only the message.
My question is: How can I change my code so that the message is sent directly to the HTML page instead? If it could be of any use, i'm using Jade.
Thanks in advance!
app.post('/file-upload', function(req, res, next) {
var fileType = req.files.thumbnail.type;
var divided = fileType.split("/");
var theType = divided[0];
if (theType === "image"){
var tmp_path = req.files.thumbnail.path;
var target_path = './public/images/' + req.files.thumbnail.name;
fs.rename(tmp_path, target_path, function(err) {
if (err) throw err;
fs.unlink(tmp_path, function() {
if (err) {
throw err;
res.send('Something happened while trying to upload, try again!');
}
res.send('File uploaded to: ' + target_path + ' - ' + req.files.thumbnail.size + ' bytes');
});
});
}
else {
res.send('No image!');
}
});
from what I understand you are trying to send a message to an already open browser window?
a few things you can do,
Ajax it, send the post, and process the return info.
Submit it as you are doing now, but set a flash message (look at http://github.com/visionmedia/express-messages) and either res.render the form page, or res.redirect to the form function
now.js or a similar solution. This would let clientside use serverside functions and serverside code to run clientside functions. So what you would do would be on submit, pass the post values to a serverside function, which will process it and trigger a clientside function (display a message)
For my money option #2 is probably the safest bet, as clients without javascript enabled will be able to use it. As for usability #1 or #3 would give a more streamlined appearance to the end user.
You can use WebSockets. I recommend using Socket.IO, it's very easy to work with. On the client-side you would have an event-handler which would use JavaScript to append the new information to that page.
You could then have the server for example say:
socket.emit('error', "Something happened while trying to upload, try again!");
and the client would use:
socket.on('error', function(data){
//alert?
alert(data);
});
http://socket.io/#how-to-use

Resources