Can't add properties to javascript object

trying to do a very simple operation in some javascript code. trying to add some properties but they are not getting added. I log object before and after and they are not getting added. I have verified that the variable containing the object to be altered is of type “object” and the new property values are all of type string. I’m just doing existingobject.newpropertyname = value;

Here is the code:

app.post('/api/users/:_id/exercises', (req, res) => {
  console.log("Path : "+req.path);
  console.log("Body.desc: "+req.body.description);
  console.log("Body.dur: "+req.body.duration);
  console.log("Body.date: "+req.body.date);
  const date = req.body.date;
  if (req.body.date === undefined){
    date = new Date().toDateString();
    console.log("current date: "+date);
    }
  const pathArray = req.path.split('/');
  const id = pathArray[pathArray.length-2];
  console.log("_id: "+id);
  user.findOne({_id: id}, (err, thisUser) => {
    if (err) console.log(err);
    console.log("thisUser :"+thisUser);
    var updatedUser = thisUser;
    updatedUser.description = req.body.description;
    updatedUser.duration = req.body.duration;
    updatedUser.date = date;
    console.log(typeof updatedUser);
    console.log(typeof req.body.description);
    console.log(typeof req.body.duration);
    console.log (typeof date);
    console.log("updatedUser: "+updatedUser);
    res.json(updatedUser);
  });
});

Your project link(s)

solution: https://replit.com/@cavasian/boilerplate-project-exercisetracker

Your browser information:

User Agent is: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.109 Safari/537.36

Challenge: Exercise Tracker

Link to the challenge:

  • thisUser is the documentObject from database
  • var updatedUser = thisUser means updatedUser refers to the same object: thisUser
  • you added .description, .duration, and .date to updatedUser, means thisUser should also has .description, .duration, and .date (objects are Reference type, not Primitive type)
    • you did not save the change into the database -, thus when you return updatedUser, updatedUser refers to thisUser that had been saved in the database, not the one you’ve changed (this is my hypothesis, I could be wrong);
  • I’d try to make a new copy of thisUser and assign it to updatedUser instead of just plainly doing updatedUser = thisUser, OR just return res.json({…fill in whatever key I want to return and the value…, e.g. res.json({ description: req.body.description… }), OR refer to documentation on using options in document update for returning a new updated document instead of previous state document on findOneAndUpdate queries. I assumed this is what you want, although you are using only findOne (search only).

You can do a findOne, and save. But if you did make a new copy, change it, and return it, without doing any change to the document in database and saving it, you’re basically returning something that did not happen at all in the database…

https://mongoosejs.com/docs/api.html#model_Model.findOne

1 Like

Yes, i know I did not save it in the database yet. Just wanted to make sure I could update and print the updated object successfully before doing that. What is weird is that after I posted the issue I just tried printing out the individual properties that I added to that updated object and they are in fact present but when I print the object itself they are not shown as being there. Very weird. (i.e. when I say print I mean console.log).
However, I now got past this by just creating an empty object then adding the properties in the object retrieved from the database and also adding the new properties that came in the post request. If I just console log that new object I get “object Object” printed but if I use console.debug(variable) then I get the entire object with all properties printed out correctly. I also return that object via res.json and I appear to get almost the right response. Here is one of the responses I got when doing it:
{"_id":“1645999793362”,“username”:“ned”,“description”:“pushup”,“duration”:“30”,“date”:“2020-11-12”}. I think the property keys should not be showing with double quotes and that probably is the last issue I need to figure out to make at least this part of it work (the challenge test for this is still failing and I suspect that is the reason). I’ll mark this resolved though since the initial issue has been fixed. Your tip about messing with the assignment was what got me going down the right path again.

I don’t think having double quote could cause anything, since object’s key is a string anyway.
object Object happened because we’re doing addition operation on a string and an object. When I want to console.log an object, I am using an array, e.g. console.log([21, 'updatedUser: ', updatedUser]), where 21 is the line number. Or, I believe we can do console.log("updatedUser: ", updatedUser) too.

figured out why the response was not passing the test after fixing the above. I was not reformatting the date if the date was an input on the post and I was not using a number for duration (had been using a string). I

1 Like

Yeah, it was not the quotes and I responded with my corrections just before I saw this from you. Interesting how you are doing your console logs for objects. The log.debug worked fine for me but I had thought I had console.logged objects successfully before but maybe not. The printing out of object Object happens even if I do the console log of the just object with no text string added to it so that is not why it happens fyi. The debug.log is definitely handy for this it appears at least in a node.js environment.

Are you using Mongoose? that Model.FindOne? Mongoose query will return Mongoose document, it is an object, but it is document object, and you cannot modify it. So this cannot work object.newfield = value. In this case, your server can only pass whatever return from db as it is. Or you can construct a new object, and “copy” that returned object to this new object. To modify Mongoose document object, you can use provided methods, if you don’t mind diving into its doc. This is one way.

Another way is to use lean() method from Mongoose so the query will be Model.findOne().lean(). This will return POJO (plain old javascript object) instead of Mongoose document object, and this POJO, you can do what you usually do with javascript object, because it is plain javascript object. Add field? modify its field? modify the date format? Using lean() also helps with computation because Mongoose document object is a lot heavier than POJO, but that is for another question.

Hope this help.

1 Like

Yes, I’m using Mongoose and the first guy that responded pointed out that I was not making a copy of the object using an assignment.
So, I created a new empty object and just assigned each property from the mongoose returned object to it and then added the additional properties to that. I have seen that .lean in places but thanks for mentioning it and what it does and how the mongoose object is different from a javascript object.

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.