1

I have a simple express app that takes a post request with some JSON data. I'd like to take that data and append it to an existing json file (If it exists). Key value pairs may be different. My current version pushes an object to an array of objects. Ideally, I'd like to add just another key/value pair:

app.post('/notes', function(req, res){
  var body = "";
  req.on('data', function(chunk){
    body += chunk;
  });
  req.on('end', function(){
    fs.readFile(__dirname + '/data/notes.json', function(err, data){
      if (err) throw err;
      console.log(body);
      var fileObj = JSON.parse(data.toString());
      var postObj = JSON.parse(body);
      fileObj.notes.push(postObj);
      var returnjson = JSON.stringify(fileObj);
      fs.writeFile(__dirname + '/data/notes.json', returnjson, function(err){
        if (err) throw err;
        res.send(returnjson);
      });
    });
  });
});

Example of what might be in notes.json:

{"note": "Dear Diary: The authorities have removed the black pants from the couch"}

This works, but I'm having trouble wrapping my head around appending whatever json comes in the post (Let's assume there is no nested data in this case).

EDIT: Not the same as just appending to a file. Needs to append to an object within a file.

6
  • 1
    When you say append, do you mean add additional JSON object lines to the file, or do you mean merge the key/value pairs of the received JSON object with the one in the file? Commented Nov 10, 2015 at 5:15
  • Add additional: So there would might be a {"note2": "This is a new note"} key value pair in the POST request to be appended to the existing notes.json file. Commented Nov 10, 2015 at 5:17
  • Possible duplicate of How to append to a file in Node? Commented Nov 10, 2015 at 5:22
  • Don't think so. It has to get added to the JSON object within the file, not after the closing brackets. Commented Nov 10, 2015 at 5:25
  • 1
    Every time you want to update the file, you read it, parse it, append the new json, serialize it, and rewrite the file. This is a lot of overhead. Could you instead just append JSON.stringify(postObj) + ',' to the the file on each post request, then do a bit of processing on the log file when you read it? (The processing might be as simple as JSON.parse('[' + fileData + ']'). Commented Nov 10, 2015 at 5:42

1 Answer 1

1

You can simply iterate through the post object with the help of for ... in loop, and add its properties to the file object. Keep in mind that in this case, if property keys are identical, their value will be overwritten. To avoid it you can make a verification with the help of Object.prototype.hasOwnProperty().

app.post('/notes', function(req, res){
  var body = "";
  req.on('data', function(chunk){
    body += chunk;
  });
  req.on('end', function(){
    fs.readFile(__dirname + '/data/notes.json', function(err, data){
      if (err) throw err;
      console.log(body);
      var fileObj = JSON.parse(data.toString());
      var postObj = JSON.parse(body);
      for(var key in postObj) { 
         fileObj[key] = postObj[key];
      }
      var returnjson = JSON.stringify(fileObj);
      fs.writeFile(__dirname + '/data/notes.json', returnjson, function(err){
        if (err) throw err;
        res.send(returnjson);
      });
    });
  });
});

Here is for ... each statement, if you don't want to overwrite properties. New properties would be generated with suffixes like: _1, _2 etc. You can also use something like shortid to be sure that properties do not repeat, but it would be more ugly and less readable.

for(var key in postObj) { 
     if(fileObj.hasOwnProperty(key)) {            
        while(true) {
            i++; 
            newKey = key + '_' + i;
            if(fileObj.hasOwnProperty(newKey) == false) {
                fileObj[newKey] = postObj[key];   
                break;
            }                
        }
     } else {
        fileObj[key] = postObj[key];
     }  
  }
Sign up to request clarification or add additional context in comments.

1 Comment

I think this is close. But if the key is the same in the postObj and fileObj, the postObj will overwrite the original. I wonder if there's a way to add a unique identifier.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.