0

Goal:

When I submit JSON data I would like the data to be properly formatted when it reaches the JSON file no matter how many entries I submit.

Problem:

So far when I submit data it is not appending properly in the JSON file; for example it appends as such:

{
 "name": "Jay Money",
 "photo": "/photo/url",
 "scores": [
   "5",
   "5",
   "5",
   "5",
   "5",
   "5",
   "5",
   "5",
   "5",
   "5"
 ]
}{
 "name": "Jay Money",
 "photo": "/photo/url",
 "scores": [
   "5",
   "5",
   "5",
   "5",
   "5",
   "5",
   "5",
   "5",
   "5",
   "5"
 ]
}

I would like it that when I append submissions it looks like this instead:

[{
 "name": "Jay Money",
 "photo": "/photo/url",
 "scores": [
   "5",
   "5",
   "5",
   "5",
   "5",
   "5",
   "5",
   "5",
   "5",
   "5"
 ]
},
{
 "name": "Jay Money",
 "photo": "/photo/url",
 "scores": [
   "5",
   "5",
   "5",
   "5",
   "5",
   "5",
   "5",
   "5",
   "5",
   "5"
 ]
}]

I am still researching but have not had any luck I am just looking for guidance.

Here is what my server.js file looks like:

// Dependencies
let express = require("express");
let bodyParser = require("body-parser");
let path = require("path");
let fs = require("fs");
// Set the port of our application
// process.env.PORT lets the port be set by Heroku
let PORT = process.env.PORT || 4000;
// Create express app instance.
let app = express();
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
// Routes
// TODO Add your routes here
app.get('/', function(req,res){
   res.sendFile('home.html', {root : __dirname + '/app/public'});
});
app.get('/survey', function(req, res){
   res.sendFile('survey.html',{root : __dirname + '/app/public'} )
});
app.post('/surveyResponse', function(req,res){
   let photo = req.body.url;
   let name = req.body.name;
   let travel = req.body.travel;
   let affection = req.body.affection;
   let family = req.body.family;
   let fitness = req.body.fitness;
   let movie = req.body.movie;
   let education = req.body.education;
   let career = req.body.career;
   let marriage = req.body.marriage;
   let children = req.body.children;
   let pets = req.body.pets;
   let sum = 0;
   let person = {
       name: name,
       photo: photo,
       scores: [
           travel,
           affection,
           family,
           fitness,
           movie,
           education,
           career,
           marriage,
           children,
           pets
       ]
   }
   let data = JSON.stringify(person, null ,2);
   fs.appendFileSync('./app/data/friends.json', data);
//finding the sum of all the numbers
   for(i in person.scores){
       sum+=Number(person.scores[i]);
   }
//------------------------------------
   res.send('Your name is ' + name + ' and your score is ' + sum );
});
// Start our server so that it can begin listening to client requests.
app.listen(PORT, function() {
 // Log (server-side) when our server has started
 console.log("Server listening on: http://localhost:" + PORT);
});

This is the code that I use to append:

let data = JSON.stringify(person, null ,2);
fs.appendFileSync('./app/data/friends.json', data);

EDIT:

I am aware of How to append JSON data to existing JSON file node.js and it does not address my issue. When I tried to incorporate the code in my code as such:

var data = fs.readFileSync('friends.json');
var json = JSON.parse(data);
json.push(...person);

fs.writeFile("friends.json", JSON.stringify(json))

I kept getting the following error message:

SyntaxError: Unexpected end of JSON input

So I tried a new variation which was removing the ... from json.push so it looks like this json.push(person).

But I keep getting the same error message. I am assuming because my file is empty it's causing an error. I am assuming I have to have the code write first then take the next steps.

Update

I found something that I feel is putting me on the right track (Save html-form data in json format in a .json file using node and express with javascript ) I cannot seem to be able to integrate it into my code. I cannot figure out why I keep getting the following error:

SyntaxError: Unexpected end of JSON input at JSON.parse () at fs.readFile (server.js:86:39) at FSReqWrap.readFileAfterClose [as oncomplete] (fs.js:511:3)

Here is my new code I am working with:

// 1. Read the existing file
    fs.readFile('./app/data/friends.json', (err, data) => {
        if (err && err.code === "ENOENT") {
            // But the file might not yet exist.  If so, just write the object and bail
            return fs.writeFile('./app/data/friends.json', JSON.stringify(person), error => console.error);
        } else if (err) {
            // Some other error
            console.error(err);
        }
        // 2. Otherwise, get its JSON content
        else {
            try {
                const fileData = JSON.parse(data);

                // 3. Append the object you want
                fileData.push(person);

                //4. Write the file back out
                return fs.writeFile('./app/data/friends.json', JSON.stringify(fileData), error => console.error)
            } catch (exception) {
                console.error(exception);
            }
        }
    });
Jermaine Subia
  • 776
  • 1
  • 7
  • 31
  • If you are only getting the error when the file is empty, what about doing something like data = data ? data : JSON.stringify([]). In other words, if the data is empty, create some minimal JSON to store in the variable (or store in the file), so it doesn't throw an error? – Maiya Sep 23 '19 at 20:00
  • 1
    @Maiya thank you I am working on that. Have to figure out an if else statement that basically states that if the file does not contain any data then use the statement you put above else append the new data. – Jermaine Subia Sep 23 '19 at 20:22
  • Oh, ok. What do you get when you console.log the result when it is an empty file? Is it a string with no length, null, or undefined? – Maiya Sep 23 '19 at 20:52
  • @maiya undefined. – Jermaine Subia Sep 24 '19 at 01:13

1 Answers1

0

Basically, I had to rewrite the function and create a newFriend that takes in the submitted information. The submitted information will then be pushed into the current JSON object and then joined.

       let newFriend = req.body; //STORING INCOMING JSON

       // PUSHING NEW MATCH INTO JSON
       friendsJSON.push(newFriend);
       fs.writeFile(path.join(__dirname + '/../data', 'friends.json'), JSON.stringify(friendsJSON, null, 2), function(err){
           if (err) throw err;
       })
Jermaine Subia
  • 776
  • 1
  • 7
  • 31