3

I'm trying to create a function that when called will update a specific object in json file. However, it updates the object as well as creating a new one.

I've tried many different methods in trying to get this to work, but all have failed. The closest I've got to it working is the code shown below, but it still doesn't do what is required.

This is my function:

var fs = require('fs');
var _ = require("underscore");

module.exports = {
  personalUpdate: function (id, forename, surname, dob, gender, callback) {    
    let rawdata = fs.readFileSync('data.json');
    let data = JSON.parse(rawdata);
    let filtered = _.where(data['students'], { id: id });
    let all = filtered[0];

    all.forename = forename;
    all.surname = surname;
    all.dob = dob;
    all.gender = gender;

    data["students"].push(all);

    fs.writeFileSync('data.json', JSON.stringify(data, null, 2), (err) => {
      if (err) throw err;
    });
    callback("success");

  }
}

And this is the JSON file that I want to update:

{
  "teachers": [
    {
      "name": "",
      "email": "",
      "password": "",
      "formGroup": "",
      "id": ""
    }
  ],
  "students": [
    {
      "surname": "test",
      "forename": "test",
      "dob": "",
      "homeAddress": "",
      "homePhone": "",
      "gender": "",
      "tutorGroup": "",
      "schoolEmail": "",
      "grades": [
        {
          "french": 8,
          "maths": 7
        }
      ],
      "id": ""
    },
    {
      "surname": "test2",
      "forename": "test2",
      "dob": "",
      "homeAddress": "test2",
      "homePhone": "",
      "gender": "",
      "tutorGroup": "",
      "schoolEmail": "",
      "grades": [
        {
          "french": 9,
          "maths": 8
        }
      ],
      "id": ""
    }

  ]
}

I had to remove and change the objects and info inside them, as it contained confidential information.

When running this function, it finds the object that is specified in the parameter. It then updates that object, but it then creates another object at the bottom of the original JSON object, which it is not supposed to.

Also, is there a better way to update the specific objects in the JSON file?

3
  • try commenting the line data["students"].push(all); to eliminate the duplicate problem, you are already updating the object in place. Commented Aug 30, 2019 at 22:32
  • Looks to me like all you need to do is to remove the line data['students'].push(all). That statement is adding a new reference to all into the data, which is why you get an additional object in the json Commented Aug 30, 2019 at 22:32
  • 1
    Thank you both it now works perfectly Commented Aug 30, 2019 at 22:40

1 Answer 1

1

tl;dr

  1. The result set is duplicating because you are pushing it into the array
  2. The change is being applied due to the variables holding the same object reference, so they are being mirrored across objects that share the same pointer.

Explanation

It creates a new one due to the data["students"].push(all); instruction.

When you manipulate objects in javascript you need to be aware of how the reference between them work, so you can avoid bugs and use them in your benefit.

For example, take this set of instructions:

let a = {"x": 1};
let b = a;
b.x = 3;
console.log(a) // it will output {"x": 3}

Notice that we:

  1. Create an object with the prop x equal 1 and assign it to the variable a
  2. Initialize a variable b with the value of a
  3. Change the property x on the variable/object b
  4. Then we can observe that the change was also reflected in the variable a, due to the object reference.

So, basically this is exactly what is happening with your instructions when you do all.forename = forename; it changes the variable all, but also the original object which it derives from.

Here is a nice reference that explains this concept more in-depth

@EDIT

I strongly advise you not using the sync version of functions like readFileSync since this blocks the event loop. Here is the official guidelines about it

Sign up to request clarification or add additional context in comments.

3 Comments

Ahh ok I see. Thank you for providing a really nice explanation. I will also update my code so it doesn't use the sync version, Thank you for your help.
This has nothing to do with "weak references".
The code was not written aware of the change, the all variable was being pushed into the array to commit the desired change. So, if you have two variables pointing to the same object, and change one of them... But I don't think I should use weak reference as explanation indeed, this documentation explains exactly this feature, so I will edit the answer to be more accurate. Thanks

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.