28

I have an object like this

==================records=========={ Id: 5114a3c21203e0d811000088,
  userId: 'test',
  sUserId: test,
  userName: 'test',
  url: 'test',
  Title: 'test'
}

I need to add a new field Name : 'test' to the above record, I tried giving records.Name = name, it didn't work.

3
  • 1
    is this record comes from a db, like mongodb, using mongoose? Commented Feb 8, 2013 at 8:54
  • @balaz: yes it came from mongoose, records.set('Name', 'test') worked for me Commented Feb 11, 2013 at 7:11
  • 1
    when do you check the value of this db record? after saving to the db? I'm asking this, because maybe if the field what you want is not in the Schema, mongoose won't save it to the database, you should add it to the schema, or call markModified. please provide more code as @neelsg suggested. Commented Feb 11, 2013 at 9:34

7 Answers 7

56

I am assuming you are trying to add a property to a returned Mongoose Document to reuse it somewhere else. Documents returned by Mongoose are not JSON objects directly, you'll need to convert them to an object to add properties to them. The following should work:

//... record is a mongoose Document
var r = record.toObject();
r.Name = 'test';
console.log("Record ",r);
Sign up to request clarification or add additional context in comments.

2 Comments

this only works if you set toObject: {} or toJSON: {} in your schema options, but yeah this still works just fine
13

Those finding this problem, OP mentioned in a comment below the original question that the solution for this problem is:

records.set('Name', 'test')

This adds a new attribute called Name having value test.

1 Comment

how do i add the new attribute to a json object i have stored in a mysql table column? now ` "1":{"lastname":"blah","firstname":"R.A.","function":"General Manager","email":"[email protected]","barcode":"33432799181"} ` and i like "1":{"lastname":"blah","firstname":"R.A.","function":"General Manager","email":"[email protected]","barcode":"33432799181", "visited":"0"}
10

Just use,

var convertedJSON = JSON.parse(JSON.stringify(mongooseReturnedDocument);

and Then,

convertedJSON.newProperty = 'Hello!' 

'Hello!' can be anything, a number, a object or JSON Object Literal.

Cheers! :)

Comments

6

I experienced a similar problem, and hope that my hours of existential frustration help others in the same situation. My inclination was to believe that documents returned via Mongoose are read-only. This is actually not true.

However, you cannot assign a property to your document that is not also in your Schema.

So, unless your schema has the following:

{
    Name: {String}
}

you will be constantly frustrated by trying to assign Name to your document.

Now, there are workarounds in the answers above that also worked for me, but they do not get to the root of the problem:

myDocument.toObject();
JSON.parse(JSON.stringify(myDocument);

These will work, but in my opinion they just hide the problem. The real issue is that Mongoose is smarter than we realized and is enforcing your schema, as it should.

4 Comments

Be careful!... you will lose numbers, etc.
JSON.parse(JSON.stringify(myDocument); this lead to performance problems. use myDocument.toObject()
@Maxwells.c, could you clarify your comment? I'm not recommending either of those approaches (those are actually recommended by the above answers), but saying they will technically work. My rec is to stick to your schema.
@misterfancypants using JSON to clone an objects doesn't have good performance because it will process to stringify the object and then parse the string to create another object. On an big project with lots of data this can slow down the application. the toObject method of mongoose document removes all the mongoose classes and methods, leading to an pure JS object. this also isn't perfect because it will take processing. The best solution if you doesn't want the mongoose document is to pass an argument to the query (i don't remember the tag) and it will return an array of pure objects.
3

You could also use the lean() method, e.g. const users = await Users.find().lean().exec()

From the mongoose documentation:

Documents returned from queries with the lean option enabled are plain javascript objects, not MongooseDocuments. They have no save method, getters/setters or other Mongoose magic applied

Comments

3

My variant.

If schema defined with {strict:false} you can simply add new property by

recorcd.newProp = 'newvalue';

If schema defined with {strict:true} you can either convert Mongoose object to object as mentioned earlier or use command

record.set('newProp','newValue',{strict:false})

See http://mongoosejs.com/docs/api.html#document_Document-schema

Comments

-1

If you have loaded this object into records, both records.Name = "test" or records['Name'] = "test" will work. You have either not loaded the object correctly, or are inserting an undefined value into it.

To test: add console.log(records.userId), this should print 'test' to the terminal.

Also add console.log(name). If you get ReferenceError: name is not defined, you obviously cannot do: records.Name = name

2 Comments

Thanks for the reply I see that console.log(records.Name) is correctly logging the value, but console.log(util.inspect(records)) doesn't have the 'Name' field, any idea why ?
@Prats: Try console.log(util.inspect(records, 1)). If it still gives the same, I would have to see your entire script to understand what is wrong.

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.