0

I need to store an array of URLs associated with number in json file. This is what I got so far:

json[message.guild.id] = {
  songs: []
};
fs.readFile("./settings.json", "utf8", (err, data) => {
  if (err) {
    throw err;
  } else {
    json[message.guild.id] = JSON.parse(data);
  }
});
json[message.guild.id].songs.push(url); // adding a new URL
fs.writeFile("./settings.json", JSON.stringify(json, null, 4), err => {
  if (err) throw err;
});

And this does work, but if I try to save next URL it just overrides the existing one. What is wrong and how I can remove one of the saved URLs?

4
  • You are writing over the file, that's why. What you want to do is to append to it. check this out : stackoverflow.com/a/11267583/6212957 Commented Jan 5, 2019 at 19:19
  • Possible duplicate of How to append to a file in Node? Commented Jan 5, 2019 at 19:20
  • It's not really clear what you are saving. It might help if you showed an example of the settings.json Commented Jan 5, 2019 at 19:31
  • Example: { "498208636234104846": { "songs": [ "https://www.youtube.com/watch?v=S81bLqpstUE" ] } } Commented Jan 5, 2019 at 19:34

2 Answers 2

1

Update 2

My first attempt overlooked the JSON issue, which I've left for posterity but you should not do because it will create an incorrect JSON object here.

However, I'm curious how you're kicking off this script. If it's the same block as you provided, you might be resetting the array for the message.guild.id every time. You could try protecting against it with something like this:

if(!json.hasOwnProperty[message.guild.id]){
    json[message.guild.id] = {};
} else if (!json[message.guild.id].hasOwnProperty('songs')){
    json[message.guild.id].songs = [];
}

Again this is just an assumption since we don't see the implementation.

Update fixed typos from paste

You need to add an options object to the writeFile method and set the flag key to 'a'. This tells writeFile to write in append mode. Documentation here and here.

json[message.guild.id] = {
  songs: []
};
fs.readFile("./settings.json", (err, data) => {
  if (err) {
    throw err;
  } else {
    json[message.guild.id] = JSON.parse(data);
  }
});
json[message.guild.id].songs.push(url); // adding a new URL
fs.writeFile("./settings.json", {encoding:"utf8", flag:'a'}, JSON.stringify(json, null, 4), err => {
  if (err) throw err;
});
Sign up to request clarification or add additional context in comments.

3 Comments

How does appending to a JSON file work? Won't this create malformed JSON?
You're absolutely correct. I was focusing on correcting the overwrite instead of the data format.
@Joe I still can't understand that, I want the structure of this file to be like: { "498208636234104846": { "songs": [ "https://www.youtube.com/watch?v=S81bLqpstUE", "https://www.youtube.com/watch?v=5lJhX6PGmMo" ] }, "457965143612194829": { "songs": [ "https://www.youtube.com/watch?v=2YeDOa2XoeF", "https://www.youtube.com/watch?v=cPOvNhET5gI" ] } } This script is fired up when user executes a command to add a song URL for a given guild ID. I hope you can understand me.
0

You are using callback functions, so you can't use it like that

json[message.guild.id] = {
  songs: []
};
fs.readFile("./settings.json", "utf8", (err, data) => {
  if (err) {
    throw err;
  } else {
    json[message.guild.id] = JSON.parse(data);
    json[message.guild.id].songs.push(url); // adding a new URL
    fs.writeFile("./settings.json", JSON.stringify(json, null, 4), err => {
      if (err) throw err;
    });
  }
});

This should work however it seems to not make sense.

Take a look at async functions, callbacks and promises. Specially how callback works, your code has to be executed inside each function

2 Comments

OP mentioned if I try to save next URL it just overrides the existing one - meaning that it's removing the existing content. So shouldn't he use the appendFile function instead of writeFile?
Yes, he should or use a flag the @joe answer stated. however the question has a problem with the callbacks

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.