问题
This is a learning struggle, and I might just be approaching this from an awkward angle, but guidance is appreciated. This project is using just HTML, Node, and Express.
I have a small app that is supposed to take survey inputs to build a 'friend' profile (essentially only a name, imgURL, and 7 question answers each a value 1-5). I want to save all the Friend objects with those properties in a JSON file in a data
sub-directory so that as new users are added, I can compare the friend objects against one another.
On my front end, I want to step through each stage one bootstrap card at a time, so I have a questions.js
file that manipulates the DOM to start with the name and imgURL and create a new 'Friend' object, then go one question at a time (printing question text from an array of strings) and capturing radio button selections (values 1-5) on("submit")
. End result is I have iterated through all the questions, grabbed the submitted values, and pushed them to a 'scores' array within the friend object, resulting thusly:
{
"name": "Ahmed",
"photo": "https://media.licdn.com/mpr/mpr/shrinknp_400_400/p/6/005/064/1bd/3435aa3.jpg",
"scores": [5, 1, 4, 4, 5, 1, 2, 5, 4, 1]
}
All of this works nicely, and I end up with good User navigation through the questions and a new Friend object with all my desired data persisting in the linked JS file.
Now how the ding-dang do I push that new Friend object as an array item in my friends.json
file? I kind of get that I need maybe an Ajax call within the questions.js
, or maybe I'm off-base and this belongs within an app.post
route in my server.js
, but so far my research and trials have only served up more confusion.
This might be a wack question, but I think there is a best practice in there I need to learn. Any insight is much appreciated!
回答1:
📨 Doing a POST request using the Fetch API
As you have mentioned, you need a POST
route in your server to handle that.
Your frontend should do an AJAX POST call to that endpoint with that newly created object. You can use the Featch API to do that:
fetch('http://localhost:8080/api/friends', {
method: "POST",
headers: {
"Content-Type": "application/json; charset=utf-8",
},
body: JSON.stringify({
name: "Ahmed",
photo: "https://media.licdn.com/.../foo.jpg",
scores: [5, 1, 4, 4, 5, 1, 2, 5, 4, 1],
}),
});
📝 Modify the data on the backend
Then, assuming this is just a simple learning example, on your backend you have two options:
- Have that
friends.json
file already loaded in memory as an array and just push a new element to it. - Load, parse and save
friends.json
on every request.
If this is meant to be a production server, then you might consider using REDIS, MongoDB or any other database that fits your needs.
Here you can see both of them:
// This will be loaded and parsed already (only used in option 1):
const friends = require("../data/friends.json");
// Only used in option 2:
const fs = require('fs');
// Tell the server to parse JSON bodies in your requests:
const bodyParser = require("body-parser");
app.use(bodyParser.json()); // Support JSON-encoded bodies.
// Get existing friends:
app.post('/api/friends', function(req, res, next) {
// Option 1, persisted in memory:
res.json(friends);
// Option 2, loaded and saved everytime:
try {
res.json(JSON.parse(fs.readFileSync("../data/friends.json")));
} catch(err) {
// JSON.parse might fail:
next(err);
}
});
// Create new friend:
app.post('/api/friends', function(req, res, next) {
// Option 1, persisted in memory:
friends.push(req.body); // This should be validated properly!
res.json(friends);
// Option 2, loaded and saved everytime:
try {
const friends = JSON.parse(fs.readFileSync("../data/friends.json"));
friends.push(req.body); // This should be validated properly!
fs.writeFileSync("../data/friends.json", JSON.stringify(friends));
res.json(friends);
} catch(err) {
// JSON.parse or fs.writeFileSync might fail:
next(err);
}
});
✨ Recommended way to use body-parser
As an additional suggestion, even though you will see body-parser
being used as app.use(bodyParser.json())
in a lot of resources out there, the recommended way to use it is to add it only to the route it is relevant for:
Express route-specific
This example demonstrates adding body parsers specifically to the routes that need them. In general, this is the most recommended way to use body-parser with Express.
So, in your case you would do:
const bodyParser = require("body-parser");
const jsonParser = bodyParser.json();
...
app.post('/api/friends', jsonParser, function(req, res, next) { ... }
来源:https://stackoverflow.com/questions/53165555/appending-a-json-file-from-js-file-in-express-application