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.

Kenji Crosland
  • 2,914
  • 6
  • 31
  • 40
  • 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? – Matthew Herbst Nov 10 '15 at 05: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. – Kenji Crosland Nov 10 '15 at 05:17
  • Possible duplicate of [How to append to a file in Node?](http://stackoverflow.com/questions/3459476/how-to-append-to-a-file-in-node) – Ziki Nov 10 '15 at 05:22
  • Don't think so. It has to get added to the JSON object within the file, not after the closing brackets. – Kenji Crosland Nov 10 '15 at 05: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 + ']')`. – keithmo Nov 10 '15 at 05:42
  • Simply extend fileObj `for (var key in postObj) { fileObj[key] = postObj[key]; }` – Molda Nov 10 '15 at 05:42

1 Answers1

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];
     }  
  }
Alexandr Lazarev
  • 12,554
  • 4
  • 38
  • 47
  • 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. – Kenji Crosland Nov 10 '15 at 06:04